package com.zbkj.crmeb.merchant.admin.service.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.crmeb.core.common.CommonResult;
import com.factory.PushWarehouseFactory;
import com.seatent.opensdk.api.DeliverGoods;
import com.seatent.opensdk.input.deliverGoods.BatchAddExceptionReplyApiInputDto;
import com.seatent.opensdk.input.deliverGoods.ShippingApiInputDto;
import com.seatent.opensdk.util.HaidaiApiUtils;
import com.utils.*;
import com.utils.jackyun.JackyunGoodsStockOutRequest;
import com.utils.jackyun.JackyunOpenHttpUtils;
import com.utils.jackyun.JkyDeliveryOrderConfirmDTO;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.front.response.OrderPayItemResponse;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.constants.SmsConstants;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.factory.CommonFactory;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.google.common.collect.Lists;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.bill.model.MerFreezeBill;
import com.zbkj.crmeb.bill.service.MerFreezeBillService;
import com.zbkj.crmeb.chant.model.ChannelMemberLevel;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.model.ChannelMerchantAccount;
import com.zbkj.crmeb.chant.service.IChannelMerchantAccountService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.logistics.LogisticsTypeEnum;
import com.zbkj.crmeb.export.vo.MerStoreOrderExcelVo;
import com.zbkj.crmeb.express.model.Express;
import com.zbkj.crmeb.express.service.ExpressService;
import com.zbkj.crmeb.express.service.LogisticService;
import com.zbkj.crmeb.express.vo.LogisticsResultVo;
import com.zbkj.crmeb.front.vo.OrderAgainVo;
import com.zbkj.crmeb.marketing.model.StoreCouponUser;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.merchant.admin.service.MerStoreOrderService;
import com.zbkj.crmeb.merchant.api.request.UpdatePickingProductRequest;
import com.zbkj.crmeb.order.oprocess.IOrderProcess;
import com.zbkj.crmeb.order.request.TmallOrderInfoRequest;
import com.zbkj.crmeb.order.request.TmallStoreOrderRequest;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.sms.request.SendSmsVo;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.store.dao.StoreOrderDao;
import com.zbkj.crmeb.store.request.OrderInfoDeliveryRequest;
import com.zbkj.crmeb.store.request.RefundGoodsRequest;
import com.zbkj.crmeb.store.request.StoreOrderRefundRequest;
import com.zbkj.crmeb.store.request.StoreOrderSearchRequest;
import com.zbkj.crmeb.store.request.StoreOrderSendRequest;
import com.zbkj.crmeb.store.request.UpdateUserAddressRequest;
import com.zbkj.crmeb.store.response.DataAnalysisResponse;
import com.zbkj.crmeb.store.response.DataAnalysisResponse.DataAnalysis;
import com.zbkj.crmeb.store.response.OrderInfoProductResponse;
import com.zbkj.crmeb.store.response.OrderNumberResponse;
import com.zbkj.crmeb.store.response.OutStoreOrderResponse;
import com.zbkj.crmeb.store.response.RefundInfo;
import com.zbkj.crmeb.store.response.RetailShopOrderDataResponse;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.StoreOrderCountItemResponse;
import com.zbkj.crmeb.store.response.StoreOrderInfoResponse;
import com.zbkj.crmeb.store.response.StoreOrderResponse;
import com.zbkj.crmeb.store.response.StoreOrderTopItemResponse;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.store.response.UserTagInfo;
import com.zbkj.crmeb.store.utilService.OrderUtils;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.model.SystemAdmin;
import com.zbkj.crmeb.system.model.SystemStore;
import com.zbkj.crmeb.system.model.SystemStoreStaff;
import com.zbkj.crmeb.system.request.SystemWriteOffOrderSearchRequest;
import com.zbkj.crmeb.system.response.StoreOrderItemResponse;
import com.zbkj.crmeb.system.response.SystemWriteOffOrderResponse;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemStoreService;
import com.zbkj.crmeb.system.service.SystemStoreStaffService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserBill;
import com.zbkj.crmeb.user.model.UserTag;
import com.zbkj.crmeb.user.service.UserBillService;
import com.zbkj.crmeb.user.service.UserService;
import com.zbkj.crmeb.user.service.UserTagService;
import com.zbkj.crmeb.wechat.service.TemplateMessageService;
import com.zbkj.crmeb.wechat.service.WeChatService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author Mr.Zhang edited by stivepeim
 * @description StoreOrderServiceImpl 接口实现
 * @date 2020-05-28
 */
@Slf4j
@Service
public class MerStoreOrderServiceImpl extends ServiceImpl<StoreOrderDao, StoreOrder> implements MerStoreOrderService {
    @Resource
    private StoreOrderDao dao;
    @Autowired
    private SystemStoreService systemStoreService;
    @Autowired
    private SystemStoreStaffService systemStoreStaffService;
    @Autowired
    private StoreOrderInfoService StoreOrderInfoService;
    @Lazy
    @Autowired
    private WeChatService weChatService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBillService userBillService;
    @Autowired
    private StoreOrderStatusService storeOrderStatusService;
    @Autowired
    private ExpressService expressService;
    @Autowired
    private TemplateMessageService templateMessageService;
    @Autowired
    private LogisticService logisticService;
    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private SmsService smsService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CommonFactory commonFactory;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private OrderInfoDeliveryService orderInfoDeliveryService;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreAccountInfoService storeAccountInfoService;
    @Autowired
    private PriceUtil priceUtil;
    @Autowired
    private SystemAdminService systemAdminService;
    @Autowired
    PurchaseGoodsService purchaseGoodsService;
    @Autowired
    StoreProductAttrResultService storeProductAttrResultService;
    @Autowired
    private MerFreezeBillService merFreezeBillService;
    @Autowired
    private IChannelMerchantAccountService channelMerchantAccountService;
    @Autowired
    private AccountFlowService accountFlowService;
    @Autowired
    UserTagService userTagService;
    @Autowired
    SupplierService supplierService;
    @Autowired
    StoreCouponUserService storeCouponUserService;
    @Autowired
    StoreOrderTaskService storeOrderTaskService;
    @Autowired
    Redisson redisson;
    @Autowired
    private UserCommissionService userCommissionService;
    @Autowired
    private StoreOrderInfoPickingService storeOrderInfoPickingService;
    private Page<StoreOrder> pageInfo;
    @Autowired
    private StoreOrderRefundApplyService storeOrderRefundApplyService;
    @Autowired
    private StoreSaleAnalysisService storeSaleAnalysisService;
    @Autowired
    private IdCardUtils idCardUtils;
    @Autowired
    private PushWarehouseFactory pushWarehouseFactory;

    @Value("${message.sendenable}")
    private String sendenable;

    //海带云
    @Value("${seatent.url.login}")
    private String login;
    @Value("${seatent.url.domain}")
    private String domain;
    @Value("${seatent.appKey}")
    private String appKey;
    @Value("${seatent.secret}")
    private String secret;
    @Value("${seatent.username}")
    private String username;
    @Value("${seatent.password}")
    private String password;
    private String accountId = "";
    private String memberId = "";
    private String token = "";

    @Override
    public StoreOrder getByOrderId(String orderId) {
        StoreOrder storeOrderPram = new StoreOrder();
//        storeOrderPram.setUnique(orderUnique);
//        storeOrderPram.setUid(userId);
        storeOrderPram.setOrderId(orderId);
        storeOrderPram.setIsDel(false);
        return getByEntityOne(storeOrderPram);
    }

    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<StoreOrder>
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public StoreOrderResponse getAdminList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
        StoreOrderResponse storeOrderResponse = new StoreOrderResponse();
        //列表数据
        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = new ArrayList<>();

        try{
            Integer aid = systemAdminService.getAdminId();
            if(aid != null && (aid == 909 || aid == 908)){
                request.setOrderType(1);
            }
        }catch (Exception e){
            log.error("针对那两位用户只能查看自建商品订单的处理异常！");
        }

        StoreOrderSearchRequest searchRequest = new StoreOrderSearchRequest();
        BeanUtils.copyProperties(request, searchRequest);
        getStoreOrderListRequest(searchRequest);

        Page<Object> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        //查询子订单
        List<StoreOrderInfo> childOrderList = dao.selectChildOrderListByUnionQuery(searchRequest);
        if (childOrderList != null && childOrderList.size() > 0) {
            storeOrderItemResponseArrayList = formatChildOrder(childOrderList, request.getMerId());
        }
        CommonPage<StoreOrderItemResponse> storeOrderItemResponseCommonPage = CommonPage.restPage(CommonPage.copyPageInfo(page, storeOrderItemResponseArrayList));
        storeOrderResponse.setList(storeOrderItemResponseCommonPage);
        //状态数量
        List<StoreOrderInfo> countList = getCount(request);
        //全部
        List<Integer> all = Stream.of(-2, -1, 0, 1, 2, 4, 5, 6).collect(Collectors.toList());
        Integer count = countList.stream().filter(e -> all.contains(e.getStatus())).map(StoreOrderInfo::getId).reduce(Integer::sum).orElse(0);
        //分组
        Map<Integer, Integer> countMap = countList.stream().filter(e -> e.getStatus() != null).collect(Collectors.toMap(StoreOrderInfo::getStatus, StoreOrderInfo::getId));

        storeOrderResponse.setStatus(
                new StoreOrderCountItemResponse(
                        count, //全部
                        getCountByStatus(countMap, OrderStatusEnum.UNPAID.getCode()), //未支付
                        getCountByStatus(countMap, OrderStatusEnum.NOT_SHIPPED.getCode()), //未发货
                        getCountByStatus(countMap, OrderStatusEnum.SHIPPED.getCode()), //待收货
                        getCountByStatus(countMap, OrderStatusEnum.COMPLETE.getCode()),//交易完成
                        getCountByStatus(countMap, OrderStatusEnum.APPLY_REFUND.getCode()),//退款中
                        getCountByStatus(countMap, OrderStatusEnum.REJECTED_SUCCESS.getCode()),//退货退款
                        getRefundedPartCount(request),//补偿性退款
                        getCountByStatus(countMap, OrderStatusEnum.CONFIRM.getCode()),//待确认
                        getCountByStatus(countMap, OrderStatusEnum.CANCEL.getCode())//已取消
                )
        );
        //头部数据
        pageParamRequest.setLimit(1);
        List<StoreOrderInfo> amountList = dao.getSumAllPriceByCondition(searchRequest);
        Map<String, StoreOrderInfo> amountMap = amountList.stream().collect(Collectors.toMap(StoreOrderInfo::getVerifyCode, e -> e));
        BigDecimal payPrice = amountList.stream().map(StoreOrderInfo::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal deductionPrice = amountList.stream().map(StoreOrderInfo::getDeductionPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        storeOrderResponse.setTop(
                new StoreOrderTopItemResponse(
                        orderUtils.getCurrentCount(request.getStatus(), storeOrderResponse.getStatus()),
                        payPrice.add(deductionPrice),
                        getPayPriceByType(amountMap, Constants.PAY_TYPE_WE_CHAT),
                        getPayPriceByType(amountMap, Constants.PAY_TYPE_YUE),
                        payPrice
                )
        );
        return storeOrderResponse;
    }

    @Override
    public StoreOrderResponse getPickingList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
        StoreOrderResponse storeOrderResponse = new StoreOrderResponse();
        //列表数据
        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = new ArrayList<>();
        //待核实订单
        if (request.getPickingType() == null) {
            throw new CrmebException("批采订单类型不能为空");
        }
        List<StoreOrderInfo> storeOrderInfoList = new ArrayList<>();
        //待核实
        Page<Object> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        if (request.getPickingType() == 1) {
            if (StringUtils.isNotBlank(request.getDateLimit())) {
                dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
                request.setStartTime(dateLimitUtilVo.getStartTime());
                request.setEndTime(dateLimitUtilVo.getEndTime());
            }
            List<StoreOrderInfoPicking> infoPickingList = dao.selectVerifyOrderInfoList(request);
            for (StoreOrderInfoPicking infoPicking : infoPickingList) {
                StoreOrderInfo storeOrderInfo = new StoreOrderInfo();
                BeanUtils.copyProperties(infoPicking, storeOrderInfo);
                storeOrderInfo.setIsVirtual(true);
                storeOrderInfoList.add(storeOrderInfo);
            }
        } else if (request.getPickingType() == 2) {
            //已核实
            StoreOrderSearchRequest searchRequest = new StoreOrderSearchRequest();
            BeanUtils.copyProperties(request, searchRequest);
            getStoreOrderListRequest(searchRequest);
            //查询子订单
            storeOrderInfoList = dao.selectChildOrderListByUnionQuery(searchRequest);
            //状态数量
            List<StoreOrderInfo> countList = getCount(request);
            //全部
            List<Integer> all = Stream.of(-2, -1, 0, 1, 2, 4, 5, 6).collect(Collectors.toList());
            Integer count = countList.stream().filter(e -> all.contains(e.getStatus())).map(StoreOrderInfo::getId).reduce(Integer::sum).orElse(0);
            //分组
            Map<Integer, Integer> countMap = countList.stream().filter(e -> e.getStatus() != null).collect(Collectors.toMap(StoreOrderInfo::getStatus, StoreOrderInfo::getId));
            storeOrderResponse.setStatus(
                    new StoreOrderCountItemResponse(
                            count, //全部
                            getCountByStatus(countMap, OrderStatusEnum.UNPAID.getCode()), //未支付
                            getCountByStatus(countMap, OrderStatusEnum.NOT_SHIPPED.getCode()), //未发货
                            getCountByStatus(countMap, OrderStatusEnum.SHIPPED.getCode()), //待收货
                            getCountByStatus(countMap, OrderStatusEnum.COMPLETE.getCode()),//交易完成
                            getCountByStatus(countMap, OrderStatusEnum.APPLY_REFUND.getCode()),//退款中
                            getCountByStatus(countMap, OrderStatusEnum.REJECTED_SUCCESS.getCode()),//退货退款
                            getRefundedPartCount(request),//补偿性退款
                            getCountByStatus(countMap, OrderStatusEnum.CONFIRM.getCode()),//待确认
                            getCountByStatus(countMap, OrderStatusEnum.CANCEL.getCode())//已取消
                    )
            );
            //头部数据
            pageParamRequest.setLimit(1);
            List<StoreOrderInfo> amountList = dao.getSumAllPriceByCondition(searchRequest);
            Map<String, StoreOrderInfo> amountMap = amountList.stream().collect(Collectors.toMap(StoreOrderInfo::getVerifyCode, e -> e));
            BigDecimal payPrice = amountList.stream().map(StoreOrderInfo::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal deductionPrice = amountList.stream().map(StoreOrderInfo::getDeductionPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            storeOrderResponse.setTop(
                    new StoreOrderTopItemResponse(
                            orderUtils.getCurrentCount(request.getStatus(), storeOrderResponse.getStatus()),
                            payPrice.add(deductionPrice),
                            getPayPriceByType(amountMap, Constants.PAY_TYPE_WE_CHAT),
                            getPayPriceByType(amountMap, Constants.PAY_TYPE_YUE),
                            payPrice
                    )
            );
        } else if (request.getPickingType() == 3) {
            if (StringUtils.isNotBlank(request.getDateLimit())) {
                dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
                request.setStartTime(dateLimitUtilVo.getStartTime());
                request.setEndTime(dateLimitUtilVo.getEndTime());
            }
            List<StoreOrderInfoPicking> infoPickingList = dao.selectVerifyOrderInfoList(request);
            for (StoreOrderInfoPicking infoPicking : infoPickingList) {
                StoreOrderInfo storeOrderInfo = new StoreOrderInfo();
                BeanUtils.copyProperties(infoPicking, storeOrderInfo);
                storeOrderInfo.setIsVirtual(true);
                storeOrderInfoList.add(storeOrderInfo);
            }
        }
        if (CollectionUtils.isNotEmpty(storeOrderInfoList)) {
            storeOrderItemResponseArrayList = formatChildOrder(storeOrderInfoList, request.getMerId());
        }
        CommonPage<StoreOrderItemResponse> storeOrderItemResponseCommonPage = CommonPage.restPage(CommonPage.copyPageInfo(page, storeOrderItemResponseArrayList));
        storeOrderResponse.setList(storeOrderItemResponseCommonPage);
        return storeOrderResponse;
    }

    private BigDecimal getPayPriceByType(Map<String, StoreOrderInfo> amoutMap, String payType) {
        BigDecimal price = BigDecimal.ZERO;
        StoreOrderInfo storeOrderInfo = amoutMap.get(payType);
        if (storeOrderInfo != null) {
            price = storeOrderInfo.getPayPrice();
        }
        return price;
    }

    private int getCountByStatus(Map<Integer, Integer> countMap, Integer status) {
        Integer count = countMap.get(status);
        return count == null ? 0 : count;
    }

    private int getRefundedPartCount(StoreOrderSearchRequest request) {
        StoreOrderSearchRequest searchRequest = new StoreOrderSearchRequest();
        BeanUtils.copyProperties(request, searchRequest);
        searchRequest.setStatus(Constants.ORDER_STATUS_REFUNDED_PART);
        getStoreOrderListRequest(searchRequest);
        return dao.getRefundedPartCount(searchRequest);
    }

    private List<StoreOrderItemResponse> formatChildOrder(List<StoreOrderInfo> childOrderList, Integer merId) {
        List<Supplier> visibleSupplier = supplierService.getVisibleSupplier(merId);
        //子订单根据order_id分组查询主订单信息
        Set<Integer> orderIdList = childOrderList.stream().map(StoreOrderInfo::getOrderId).collect(Collectors.toSet());
        List<StoreOrder> storeOrderList = dao.selectList(Wrappers.lambdaQuery(StoreOrder.class).in(StoreOrder::getId, orderIdList).orderByDesc(StoreOrder::getId));
        //下单用户列表
        Set<Integer> userIdList = storeOrderList.stream().map(StoreOrder::getUid).collect(Collectors.toSet());
        List<User> userList = userService.list(Wrappers.lambdaQuery(User.class).in(User::getUid, userIdList));
        //用户标签列表
        Map<Integer, List<UserTagInfo>> tagMap = new HashMap<>();
        //推广人列表
        Map<Integer, User> spreadMap = new HashMap<>();
        //团长列表
        Set<Integer> leaderIdList = storeOrderList.stream().filter(e -> null != e.getLeaderId() && 0 != e.getLeaderId()).map(StoreOrder::getLeaderId).collect(Collectors.toSet());
        Map<Integer, User> leaderMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(leaderIdList)) {
            List<User> leaderList = userService.list(Wrappers.lambdaQuery(User.class).in(User::getUid, leaderIdList));
            leaderMap = leaderList.stream().collect(Collectors.toMap(User::getUid, e -> e));
        }
        userList.forEach(e -> {
            if (spreadMap.get(e.getUid()) == null) {
                User spread = Optional.ofNullable(userService.getById(e.getSpreadUid())).orElse(new User());
                spreadMap.put(e.getUid(), spread);
            }
            List<UserTagInfo> userTagInfoList = new ArrayList<>();
            if (StringUtils.isNotBlank(e.getTagIds()) && tagMap.get(e.getUid()) == null) {
                List<Integer> tagIdList = Stream.of(e.getTagIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                List<UserTag> UserTagList = userTagService.list(Wrappers.lambdaQuery(UserTag.class).in(UserTag::getId, tagIdList));
                userTagInfoList = UserTagList.stream().map(tag -> new UserTagInfo().setTagId(tag.getId()).setTagName(tag.getName())).collect(Collectors.toList());
                tagMap.put(e.getUid(), userTagInfoList);
            }
        });
        Map<Integer, List<StoreOrderInfo>> infoMap = childOrderList.stream().collect(Collectors.groupingBy(StoreOrderInfo::getOrderId));
        //商品信息
        List<Integer> productIdList = childOrderList.stream().map(StoreOrderInfo::getProductId).distinct().collect(Collectors.toList());
        List<StoreProduct> productList = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery().in(StoreProduct::getId, productIdList)
                .select(StoreProduct::getId, StoreProduct::getSuppliersId, StoreProduct::getSuppliersName));
        Map<Integer, StoreProduct> productMap = productList.stream().collect(Collectors.toMap(StoreProduct::getId, e -> e));
        //订单物流
        List<Integer> orderInfoIdList = childOrderList.stream().filter(e -> !BooleanUtils.isTrue(e.getIsVirtual())).map(StoreOrderInfo::getId).distinct().collect(Collectors.toList());
        Map<Integer, OrderInfoDelivery> deliveryMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(orderInfoIdList)) {
            List<OrderInfoDelivery> deliveryList = orderInfoDeliveryService.list(Wrappers.<OrderInfoDelivery>lambdaQuery().in(OrderInfoDelivery::getOrderInfoId, orderInfoIdList)
                    .groupBy(OrderInfoDelivery::getOrderInfoId).orderByDesc(OrderInfoDelivery::getCreateTime));
            deliveryMap = deliveryList.stream().collect(Collectors.toMap(OrderInfoDelivery::getOrderInfoId, e -> e));
        }
        //采购单信息
        Map<Integer, List<PurchaseGoods>> purchaseGoodsMap = new HashMap<>();
        List<Integer> filterOrderInfoIdList = childOrderList.stream().filter(e -> !BooleanUtils.isTrue(e.getIsVirtual())).filter(e -> !Objects.equals(e.getIsEurope(), ProductTypeEnum.INSIDE.getCode()) && !Objects.equals(e.getAutonomous(), 1)).map(StoreOrderInfo::getId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(filterOrderInfoIdList)) {
            List<PurchaseGoods> purchaseList = purchaseGoodsService.list(Wrappers.lambdaQuery(PurchaseGoods.class).eq(PurchaseGoods::getPushStatus, 1).eq(PurchaseGoods::getPushType, 0)
                    .in(PurchaseGoods::getStoreOrderInfoId, filterOrderInfoIdList));
            purchaseGoodsMap = purchaseList.stream().collect(Collectors.groupingBy(PurchaseGoods::getStoreOrderInfoId));
        }
        //备注
        List<String> childOrderNoList = childOrderList.stream().map(StoreOrderInfo::getChildOrderNumber).distinct().collect(Collectors.toList());
        Map<String, String> noteMap = storeOrderStatusService.getNoteMap(childOrderNoList, Constants.ORDER_MERCHANT_NOTE);

        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = new ArrayList<>();
        for (StoreOrder storeOrder : storeOrderList) {
            StoreOrderItemResponse storeOrderItemResponse = new StoreOrderItemResponse();
            BeanUtils.copyProperties(storeOrder, storeOrderItemResponse);
            //配送方式
            storeOrderItemResponse.setShippingType(storeOrder.getShippingType());
            //使用积分
            storeOrderItemResponse.setUseIntegral(new BigDecimal(storeOrder.getUseIntegral()));
            //支付方式
            storeOrderItemResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));
            //下单用户
            storeOrderItemResponse.setOrderCreateName(storeOrder.getCreateName());
            storeOrderItemResponse.setUserTagInfoList(tagMap.get(storeOrder.getUid()));
            if (spreadMap.get(storeOrder.getUid()) != null) {
                storeOrderItemResponse.getSpreadInfo().setId(spreadMap.get(storeOrder.getUid()).getUid());
                storeOrderItemResponse.getSpreadInfo().setName(spreadMap.get(storeOrder.getUid()).getNickname());
            }
            Integer leaderId = storeOrder.getLeaderId();
            if(null != leaderId && 0 != leaderId){
                User leader = leaderMap.get(leaderId);
                if(null != leader) {
                    storeOrderItemResponse.setLeaderId(leader.getUid());
                    storeOrderItemResponse.setLeaderName(leader.getNickname());
                }
            }
            //子订单处理信息
            List<OrderInfoProductResponse> childOrderInfoList = new ArrayList<>();
            List<StoreOrderInfo> orderInfoList = infoMap.get(storeOrder.getId());
            for (StoreOrderInfo storeOrderInfo : orderInfoList) {
                StoreProduct product = productMap.get(storeOrderInfo.getProductId());
                OrderInfoProductResponse orderInfoProductResponse = new OrderInfoProductResponse();
                //解析商品详情JSON
                StoreOrderInfoVo infoVo = new StoreOrderInfoVo();
                BeanUtils.copyProperties(storeOrderInfo, infoVo, "info");
                infoVo.setInfo(JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class));
                if (null != product) {
                    infoVo.getInfo().getProductInfo().setSupplierName(product.getSuppliersName());
                    orderInfoProductResponse.setSuppliersId(product.getSuppliersId());
                    orderInfoProductResponse.setSuppliersName(product.getSuppliersName());
                }
                StoreProductAttrValue attrInfo = infoVo.getInfo().getProductInfo().getAttrInfo();
                orderInfoProductResponse.setSkuId(attrInfo.getSourceSkuId());
                orderInfoProductResponse.setBarCode(attrInfo.getBarCode());
                orderInfoProductResponse.setCost(attrInfo.getCost());
                orderInfoProductResponse.setSourceCost(attrInfo.getSourceCost());
                orderInfoProductResponse.setOtPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getOtPrice());
                orderInfoProductResponse.setOrderInfoId(infoVo.getId());
                orderInfoProductResponse.setProductId(infoVo.getProductId());
                orderInfoProductResponse.setCartNum(infoVo.getNum() == null ? infoVo.getInfo().getCartNum() : infoVo.getNum());
                orderInfoProductResponse.setImage(attrInfo.getImage());
                orderInfoProductResponse.setStoreName(infoVo.getInfo().getProductInfo().getStoreName());
                orderInfoProductResponse.setChildOrderNumber(infoVo.getChildOrderNumber());
                orderInfoProductResponse.setStatus(infoVo.getStatus());
                orderInfoProductResponse.setProductPaidPrice(attrInfo.getProductPaidPrice());
                orderInfoProductResponse.setPaidPrice(attrInfo.getPaidPrice());
                orderInfoProductResponse.setDeductionPrice(attrInfo.getDeductionPrice());
                orderInfoProductResponse.setUseIntegral(attrInfo.getUseIntegral());
                BigDecimal subTotalPrice = attrInfo.getSubTotalPrice() == null ? attrInfo.getPrice().add(attrInfo.getTaxPrice() == null ? BigDecimal.ZERO : attrInfo.getTaxPrice().add(attrInfo.getSecondPrice() == null ? BigDecimal.ZERO : attrInfo.getSecondPrice())) : attrInfo.getSubTotalPrice();
                orderInfoProductResponse.setSubTotalPrice(subTotalPrice);
                //橙子商品设置keyword为itemCode
                String keyword = infoVo.getInfo().getProductInfo().getKeyword();
                if (ProductTypeEnum.ORANGE.getCode().equals(infoVo.getInfo().getProductInfo().getIsEurope())) {
                    StoreProductAttrResult result = storeProductAttrResultService.getByProductId(infoVo.getInfo().getProductId());
                    JSONArray jsonArray = JSONArray.parseArray(result.getResult());
                    for (Object o : jsonArray) {
                        JSONObject jsonObject = JSONObject.parseObject(o.toString());
                        if (Objects.equals(jsonObject.get("sourceSkuId"), infoVo.getInfo().getProductInfo().getAttrInfo().getSourceSkuId())) {
                            keyword = (String) jsonObject.get("skuCode");
                        }
                    }
                }
                orderInfoProductResponse.setKeyword(keyword);
                orderInfoProductResponse.setSuk(infoVo.getInfo().getProductInfo().getAttrInfo().getSuk());
                orderInfoProductResponse.setTempName(StockAreaTempEnum.getByTempId(infoVo.getInfo().getProductInfo().getTempId()).getStockAreaName());
                orderInfoProductResponse.setPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getPrice());
                orderInfoProductResponse.setTotalPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getPrice().multiply(new BigDecimal(infoVo.getInfo().getCartNum())));
                OrderInfoDelivery delivery = deliveryMap.get(infoVo.getId());
                if (Objects.equals(storeOrderInfo.getIsEurope(), ProductTypeEnum.INSIDE.getCode())) {
                    orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.NO_PROCURE.getType());
                } else if (Objects.equals(storeOrderInfo.getAutonomous(), 1)) {
                    orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.AUTO_PROCURE.getType());
                } else {
                    if (BooleanUtils.isTrue(storeOrderInfo.getIsVirtual())) {
                        orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.FOR_PROCURE.getType());
                    } else {
                        List<PurchaseGoods> purchaseGoodsList = purchaseGoodsMap.get(infoVo.getId());
                        orderInfoProductResponse.setProcureStatus((CollectionUtils.isEmpty(purchaseGoodsList) && delivery == null) ? ProcureStatusEnum.FOR_PROCURE.getType() : ProcureStatusEnum.PROCURE.getType());
                        if (CollectionUtils.isNotEmpty(purchaseGoodsList)) {
                            orderInfoProductResponse.setDeliveryOrderNoList(purchaseGoodsList.stream().map(PurchaseGoods::getChannelOrderSn).collect(Collectors.toList()));
                        }
                    }
                }
                if (!BooleanUtils.isTrue(storeOrderInfo.getIsVirtual())) {
                    orderInfoProductResponse.setDelivery(delivery);
                }
                orderInfoProductResponse.setOrderCode(Integer.toString(Integer.parseInt(infoVo.getOrderId() + "" + infoVo.getId()), 36).toUpperCase());
                orderInfoProductResponse.setDeliveryAddress(infoVo.getDeliveryAddress());
                orderInfoProductResponse.setFirstPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getFirstPrice());
                orderInfoProductResponse.setSecondPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getSecondPrice());
                orderInfoProductResponse.setTaxPrice(infoVo.getInfo().getProductInfo().getAttrInfo().getTaxPrice());
                orderInfoProductResponse.setBrandName(infoVo.getInfo().getProductInfo().getBrandName());
                orderInfoProductResponse.setRefundReasonTime(storeOrderInfo.getRefundReasonTime());
                orderInfoProductResponse.setRefundReasonWapImg(storeOrderInfo.getRefundReasonWapImg());
                orderInfoProductResponse.setRefundReasonWapExplain(storeOrderInfo.getRefundReasonWapExplain());
                orderInfoProductResponse.setRefundReasonWap(storeOrderInfo.getRefundReasonWap());
                orderInfoProductResponse.setRefundReason(storeOrderInfo.getRefundReason());
                orderInfoProductResponse.setNote(noteMap.get(storeOrderInfo.getChildOrderNumber()));
                //判断供应商名称是否商户可见
                if (visibleSupplier.stream().noneMatch(supplier -> Objects.equals(supplier.getId().toString(), orderInfoProductResponse.getSuppliersId() + ""))) {
                    orderInfoProductResponse.setSuppliersName(null);
                }
                childOrderInfoList.add(orderInfoProductResponse);
            }
            storeOrderItemResponse.setChildOrderList(childOrderInfoList);
            storeOrderItemResponseArrayList.add(storeOrderItemResponse);
        }
        return storeOrderItemResponseArrayList;
    }

    private void getStoreOrderListRequest(StoreOrderSearchRequest request) {
        if (StringUtils.isNotBlank(request.getDateLimit())) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
            request.setStartTime(dateLimitUtilVo.getStartTime());
            request.setEndTime(dateLimitUtilVo.getEndTime());
        }
        String where = " a.mer_id = " + request.getMerId();
        if (BooleanUtils.isTrue(request.getIsPicking())) {
            where += " and a.picking_id != 0 ";
        } else {
            where += " and a.picking_id = 0 ";
        }
        if (request.getShippingType() != null) {
            where += " and a.shipping_type  = " + request.getShippingType();
        }
        if (request.getCouponId() != null) {
            where += " and a.coupon_id in (select id from eb_store_coupon_user where coupon_id = " + request.getCouponId() + " ) ";
        }
        String status = request.getStatus();
        if (null != status) {
            List<Integer> orderStatusList = new ArrayList<>();
            Integer orderStatus = null; //订单状态
            Integer refundStatus = null; //退款状态
            switch (status) {
                case Constants.ORDER_STATUS_ALL:
                    orderStatusList = Stream.of(0, 1, 2, 4, 5, 6, -1, -2).collect(Collectors.toList());
                    break;
                case Constants.ORDER_STATUS_UNPAID: //未支付
                    orderStatus = 0;
                    break;
                case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                    orderStatus = 1;
                    break;
                case Constants.ORDER_STATUS_SPIKE: //待收货
                    orderStatus = 2;
                    break;
                case Constants.ORDER_STATUS_BARGAIN: //待评价
                    orderStatus = 3;
                    break;
                case Constants.ORDER_STATUS_COMPLETE: //交易完成
                    orderStatus = 4;
                    break;
                case Constants.ORDER_STATUS_CANCEL: //取消
                    orderStatus = 5;
                    break;
                case Constants.ORDER_STATUS_REFUNDING: //退款中
                    orderStatus = -1;
                    break;
                case Constants.ORDER_STATUS_REFUNDED: //退货退款
                    orderStatus = -2;
                    break;
                case Constants.ORDER_STATUS_REFUNDED_PART: //补偿性退款
                    refundStatus = 3;
                    break;
                case Constants.ORDER_STATUS_CONFIRM: //待确认
                    orderStatus = OrderStatusEnum.CONFIRM.getCode();
                    break;
                default:
                    //其他传状态不存在的-99
                    orderStatus = -99;
                    break;
            }
            if (CollectionUtils.isNotEmpty(orderStatusList)) {
                where += " and b.status in " + orderStatusList.toString().replace("[", "(").replace("]", ")");
            }
            if (orderStatus != null) {
                where += " and b.status  = " + orderStatus;
            }

            if (refundStatus != null) {
                where += " and b.refund_status  = " + refundStatus;
            }

        }
        request.setWhere(where);
        request.setIsIntegral(request.getIsIntegral());
        if (StringUtils.isNotBlank(request.getCateIdList())) {
            List<String> cateIdList = Arrays.asList(request.getCateIdList().split(","));
            request.setCateIdListSearch(cateIdList);
        }
    }

    /**
     * 分页
     *
     * @param request          StoreOrderSearchRequest 请求参数
     * @param pageParamRequest PageParamRequest 分页
     * @return List<StoreOrder>
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    @Override
    public List<StoreOrder> getList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
        this.pageInfo = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mer_id", request.getMerId());
        getRequestWhere(queryWrapper, request);
        getStatusWhere(queryWrapper, request.getStatus());
        getIsDelWhere(queryWrapper, false);
        getIsSystemDelWhere(queryWrapper, false);
        queryWrapper.orderByDesc("id");
        return dao.selectList(queryWrapper);
    }

    /**
     * H5 订单列表
     *
     * @param storeOrder       查询参数
     * @param pageParamRequest 分页参数
     * @return 查询结果
     */
    @Override
    public List<StoreOrder> getUserOrderList(StoreOrder storeOrder, PageParamRequest pageParamRequest) {
        this.pageInfo = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        if (!Objects.isNull(storeOrder.getStatus())) {
            statusApiByWhere(lqw, storeOrder.getStatus());
        }
        if (null != storeOrder.getId()) {
            lqw.eq(StoreOrder::getId, storeOrder.getId());
        }
        if (null != storeOrder.getDeliveryId()) {
            lqw.eq(StoreOrder::getDeliveryId, storeOrder.getDeliveryId());
        }
        if (null != storeOrder.getUnique()) {
            lqw.eq(StoreOrder::getUnique, storeOrder.getUnique());
        }
        if (null != storeOrder.getIsDel()) {
            lqw.eq(StoreOrder::getIsDel, storeOrder.getIsDel());
        }
        if (null != storeOrder.getUid()) {
            lqw.eq(StoreOrder::getUid, storeOrder.getUid());
        }
        if (null != storeOrder.getOrderId()) {
            lqw.eq(StoreOrder::getOrderId, storeOrder.getOrderId());
        }
        if (null != storeOrder.getPayTime()) {
            lqw.eq(StoreOrder::getPayTime, storeOrder.getPayTime());
        }
        if (null != storeOrder.getStoreId()) {
            lqw.eq(StoreOrder::getStoreId, storeOrder.getStoreId());
        }
        if (null != storeOrder.getShippingType()) {
            lqw.eq(StoreOrder::getShippingType, storeOrder.getShippingType());
        }
        if (null != storeOrder.getPayType()) {
            lqw.eq(StoreOrder::getPayType, storeOrder.getPayType());
        }
        if (null != storeOrder.getUidList() && storeOrder.getUidList().size() > 0) {
            lqw.in(StoreOrder::getUid, storeOrder.getUidList());
            lqw.in(StoreOrder::getStatus, 1, 2, 3, 4);
        }
        lqw.orderByDesc(StoreOrder::getCreateTime);
        return dao.selectList(lqw);
    }

    /**
     * 创建订单
     *
     * @param storeOrder 订单参数
     * @return 结果标识
     */
    @Override
    public boolean create(StoreOrder storeOrder) {
        return dao.insert(storeOrder) > 0;
    }

    /**
     * 注意 再次购买的逻辑 orderAgain 存redis 后confirm 接口时 从redis中获取数据再下单 调用orderCreate时 isNew=true 走直接购买逻辑
     *
     * @param userId        用户id
     * @param productId     产品id
     * @param cartNum       商品数量
     * @param orderUnique   商品唯一标识
     * @param type          商品默认类型
     * @param isNew         isNew
     * @param combinationId 拼团id
     * @param skillId       秒杀id
     * @param bargainId     砍价id
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public List<String> addCartAgain(Integer userId, Integer productId, Integer cartNum, String orderUnique, String type, boolean isNew, Integer combinationId, Integer skillId, Integer bargainId) {
        List<String> cacheIdsResult = new ArrayList<>();
        // todo 营销活动二期处理

        // 检测订单是否有效
        StoreOrder storeOrderPram = new StoreOrder();
        storeOrderPram.setUnique(orderUnique);
        storeOrderPram.setUid(userId);
        storeOrderPram.setIsDel(false);
        StoreOrder existOrder = getByEntityOne(storeOrderPram);
        if (null == existOrder) throw new CrmebException("订单不存在");
        OrderAgainVo orderAgainVo = orderUtils.tidyOrder(existOrder, true, false);
        Long cacheKey = DateUtil.getTime() + userId;
        List<StoreCartResponse> orderAgainCache = new ArrayList<>();
        for (StoreOrderInfoVo so : orderAgainVo.getCartInfo()) {
            // 判断商品是否有效
            StoreProduct storeProductPram = new StoreProduct();
            storeProductPram.setId(productId);
            storeProductPram.setIsDel(false);
            storeProductPram.setIsShow(true);
            StoreProduct existProduct = storeProductService.getByEntity(storeProductPram);
            if (null == existProduct) throw new CrmebException("该商品已下架或者删除");

            // 判断商品对应属性是否有效
            StoreProductAttrValue apAttrValuePram = new StoreProductAttrValue();
            apAttrValuePram.setProductId(productId);
            apAttrValuePram.setSourceSkuId(so.getUnique());
            apAttrValuePram.setType(0);
            StoreProductAttrValue existSPAttrValue = storeProductAttrValueService.getByEntity(apAttrValuePram);
            if (null == existSPAttrValue) throw new CrmebException("请选择有效的商品属性");
            if (existSPAttrValue.getStock() < cartNum) throw new CrmebException("该商品库存不足");
            // 添加有效商品至缓存 缓存为购物车对象
            if (isNew) {
                StoreCartResponse storeCartResponse = new StoreCartResponse();
                cacheIdsResult.add(cacheKey + "");
                storeCartResponse.setId(cacheKey);
                storeCartResponse.setType(type);
                storeCartResponse.setProductId(productId);

                storeCartResponse.setProductAttrUnique(so.getUnique());
                storeCartResponse.setCartNum(cartNum);
                StoreProductCartProductInfoResponse spcpInfo = new StoreProductCartProductInfoResponse();
                BeanUtils.copyProperties(existProduct, spcpInfo);
                spcpInfo.setAttrInfo(existSPAttrValue);
                storeCartResponse.setProductInfo(spcpInfo);
                storeCartResponse.setTrueStock(storeCartResponse.getProductInfo().getAttrInfo().getStock());
                storeCartResponse.setCostPrice(storeCartResponse.getProductInfo().getAttrInfo().getCost());
//                storeCartResponse.setTruePrice(BigDecimal.ZERO);
                storeCartResponse.setTruePrice(existSPAttrValue.getPrice());
                storeCartResponse.setVipTruePrice(BigDecimal.ZERO);
                orderAgainCache.add(storeCartResponse);
            }
        }
        orderUtils.setCacheOrderAgain(cacheKey + "", orderAgainCache);

        return cacheIdsResult;
//        else{ // else 中的逻辑暂时未使用到
//         StoreCart storeCartNewPram = new StoreCart();
//         storeCartNewPram.setUid(userId);
//         storeCartNewPram.setProductId(productId);
//         storeCartNewPram.setCartNum(cartNum);
//         storeCartNewPram.setProductAttrUnique(productAttrUnique);
//         storeCartNewPram.setIsNew(isNew);
//         storeCartNewPram.setType(type);
//         storeCartNewPram.setCombinationId(combinationId);
//         storeCartNewPram.setCreateTime(DateUtil.nowDateTime());
//         storeCartNewPram.setBargainId(bargainId);
//         storeCartNewPram.setSeckillId(skillId);
//         saveCate(storeCartNewPram);
//         return storeCartNewPram;
//        }
    }

    /**
     * 订单基本查询
     *
     * @param storeOrder 订单参数
     * @return 订单查询结果
     */
    @Override
    public List<StoreOrder> getByEntity(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.setEntity(storeOrder);
        return dao.selectList(lqw);
    }

    /**
     * 订单基本查询一条
     *
     * @param storeOrder 参数
     * @return 查询结果
     */
    @Override
    public StoreOrder getByEntityOne(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.setEntity(storeOrder);
        return dao.selectOne(lqw);
    }

    /**
     * 更新订单信息
     *
     * @param storeOrder 更新参数
     * @return 更新结果
     */
    @Override
    public boolean updateByEntity(StoreOrder storeOrder) {
        LambdaUpdateWrapper<StoreOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if (null != storeOrder.getPayPrice()) {
            lambdaUpdateWrapper.set(StoreOrder::getPayPrice, storeOrder.getPayPrice());
        }
        if (null != storeOrder.getPayType()) {
            lambdaUpdateWrapper.set(StoreOrder::getPayType, storeOrder.getPayType());
        }
        if (null != storeOrder.getVerifyCode()) {
            lambdaUpdateWrapper.set(StoreOrder::getVerifyCode, storeOrder.getVerifyCode());
        }
        if (null != storeOrder.getShippingType()) {
            lambdaUpdateWrapper.set(StoreOrder::getShippingType, storeOrder.getShippingType());
        }
        if (null != storeOrder.getOrderId()) {
            lambdaUpdateWrapper.set(StoreOrder::getOrderId, storeOrder.getOrderId());
        }
        if (null != storeOrder.getIsChannel()) {
            lambdaUpdateWrapper.set(StoreOrder::getIsChannel, storeOrder.getIsChannel());
        }
        if (null != storeOrder.getDeliveryType()) {
            lambdaUpdateWrapper.set(StoreOrder::getDeliveryType, storeOrder.getDeliveryType());
        }
        if (null != storeOrder.getPaid()) {
            lambdaUpdateWrapper.set(StoreOrder::getPaid, storeOrder.getPaid());
        }
        if (null != storeOrder.getStatus()) {
            lambdaUpdateWrapper.set(StoreOrder::getStatus, storeOrder.getStatus());
        }
        if (null != storeOrder.getRefundStatus()) {
            lambdaUpdateWrapper.set(StoreOrder::getRefundStatus, storeOrder.getRefundStatus());
        }
        if (null != storeOrder.getRefundPrice()) {
            lambdaUpdateWrapper.set(StoreOrder::getRefundPrice, storeOrder.getRefundPrice());
        }
        if (null != storeOrder.getUid()) {
            lambdaUpdateWrapper.set(StoreOrder::getUid, storeOrder.getUid());
        }
        if (null != storeOrder.getIsDel()) {
            lambdaUpdateWrapper.set(StoreOrder::getIsDel, storeOrder.getIsDel());
        }
        if (null != storeOrder.getIsSystemDel()) {
            lambdaUpdateWrapper.set(StoreOrder::getIsSystemDel, storeOrder.getIsSystemDel());
        }
        if (null != storeOrder.getStoreId()) {
            lambdaUpdateWrapper.set(StoreOrder::getStoreId, storeOrder.getStoreId());
        }
        if (null != storeOrder.getPayTime()) {
            lambdaUpdateWrapper.set(StoreOrder::getPayTime, storeOrder.getPayTime());
        }
        lambdaUpdateWrapper.eq(StoreOrder::getId, storeOrder.getId());
        return update(lambdaUpdateWrapper);
    }

    /**
     * 余额支付
     *
     * @param currentUser 当前用户
     * @return 支付结果
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public boolean yuePay(StoreOrder storeOrder, User currentUser) {

        //判断账户余额是否足够
        if (currentUser.getNowMoney().compareTo(storeOrder.getPayPrice()) < 0) {
            throw new CrmebException("余额不足");
        }

        //余额支付操作
        boolean updateUserResult = paySuccess(storeOrder, currentUser);

        //余额支付成功之后, 处理事务
        if (updateUserResult) {
            orderPayService.afterPaySuccess(storeOrder);
        }

        return updateUserResult;
    }


    /**
     * 余额支付操作
     *
     * @param storeOrder  当前支付订单
     * @param currentUser 当前用户
     * @return 成功处理结果
     */
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public boolean paySuccess(StoreOrder storeOrder, User currentUser) {

        //更新用户的余额
        boolean result = updateUserNowMoney(storeOrder, currentUser);

        //更新用户积分 - 扣减积分
        //updateUserIntegral(storeOrder, currentUser);

        return result;
    }

    /**
     * 余额支付操作 - 更新用户的余额
     */
    public boolean updateUserNowMoney(StoreOrder storeOrder, User currentUser) {
        try {
            BigDecimal priceSubtract = currentUser.getNowMoney().subtract(storeOrder.getPayPrice());
            return userService.updateNowMoney(currentUser.getUid(), priceSubtract);
        } catch (Exception e) {
            throw new CrmebException("余额支付 - 更新用户的余额失败");
        }
    }

    /**
     * 余额支付操作 - 更新用户积分
     * @param storeOrder
     * @param currentUser
     */
//    private void updateUserIntegral(StoreOrder storeOrder,User currentUser) {
//        //是否开启积分
//        User info = userService.getInfo();
//        Integer enableIntegral = channelMerchantService.getById(info.getMerId()).getEnableIntegral();
//        if(storeOrder.getUseIntegral() > 0&&enableIntegral==1){
//            BigDecimal useIntegral = BigDecimal.valueOf(storeOrder.getUseIntegral(),0);
//            currentUser.setIntegral(currentUser.getIntegral().subtract(useIntegral));
//            userService.updateBase(currentUser);
//
//            boolean disIntegle = true;
//
//            BigDecimal deductionPrice = BigDecimal.ZERO;
//            if (deductionPrice.intValue()==0)return;
//            UserBill userBill = new UserBill();
//            userBill.setTitle("积分抵扣");
//            userBill.setUid(currentUser.getUid());
//            userBill.setCategory("integral");
//            userBill.setType("deduction");
//            userBill.setNumber(useIntegral);
//            userBill.setLinkId(storeOrder.getId() + "");
//            userBill.setBalance(currentUser.getIntegral());
//
//            userBill.setMark("购买商品使用" + userBill.getNumber() + "积分抵扣" + deductionPrice + "元");
//            boolean userBillSaveResult = userBillService.save(userBill);
//            disIntegle = disIntegle && userBillSaveResult;
//
//            if (!disIntegle) {
//                throw new CrmebException("使用积分抵扣失败");
//            }
//        }
//        userService.userPayCountPlus(currentUser);
//    }

    /**
     * 核销列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<StoreOrder>
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public SystemWriteOffOrderResponse getWriteOffList(SystemWriteOffOrderSearchRequest request, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String where = " is_del = 0";
//        String where = " is_del = 0 and paid = 1";
        //时间
        if (!StringUtils.isBlank(request.getData())) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getData());
            where += " and (create_time between '" + dateLimit.getStartTime() + "' and '" + dateLimit.getEndTime() + "' )";
        }

        if (!StringUtils.isBlank(request.getKeywords())) {
            where += " and (real_name like '% " + request.getKeywords() + " %' or user_phone = '" + request.getKeywords() + "' or order_id = '" + request.getKeywords() + "' or id = '" + request.getKeywords() + "' )";
        }

        if (request.getStoreId() != null && request.getStoreId() > 0) {
            where += " and store_id = " + request.getStoreId();
        }

        SystemWriteOffOrderResponse systemWriteOffOrderResponse = new SystemWriteOffOrderResponse();
        BigDecimal totalPrice = dao.getTotalPrice(where);
        BigDecimal price = new BigDecimal(BigInteger.ZERO);
        if (totalPrice == null) {
            totalPrice = price;
        }
        systemWriteOffOrderResponse.setOrderTotalPrice(totalPrice);   //订单总金额

        BigDecimal refundPrice = dao.getRefundPrice(where);
        if (refundPrice == null) {
            refundPrice = price;
        }
        systemWriteOffOrderResponse.setRefundTotalPrice(refundPrice); //退款总金额
        systemWriteOffOrderResponse.setRefundTotal(dao.getRefundTotal(where));  //退款总单数


        Page<StoreOrder> storeOrderPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        lambdaQueryWrapper.apply(where);
        lambdaQueryWrapper.eq(StoreOrder::getRefundStatus, 0);
        lambdaQueryWrapper.orderByDesc(StoreOrder::getId);
        List<StoreOrder> storeOrderList = dao.selectList(lambdaQueryWrapper);

        if (storeOrderList.size() < 1) {
            systemWriteOffOrderResponse.setList(CommonPage.restPage(new PageInfo<>()));
            return systemWriteOffOrderResponse;
        }

        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = formatOrder(storeOrderList);

        systemWriteOffOrderResponse.setTotal(storeOrderPage.getTotal()); //总单数
        systemWriteOffOrderResponse.setList(CommonPage.restPage(CommonPage.copyPageInfo(storeOrderPage, storeOrderItemResponseArrayList)));

        return systemWriteOffOrderResponse;
    }

    /**
     * 格式化订单信息，对外输出一致
     *
     * @param storeOrderList List<StoreOrder> 订单列表
     * @return List<StoreOrderItemResponse>
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    private List<StoreOrderItemResponse> formatOrder(List<StoreOrder> storeOrderList) {
        List<StoreOrderItemResponse> storeOrderItemResponseArrayList = new ArrayList<>();
        if (null == storeOrderList || storeOrderList.size() < 1) {
            return storeOrderItemResponseArrayList;
        }
        //门店id
        List<Integer> storeIdList = storeOrderList.stream().map(StoreOrder::getStoreId).distinct().collect(Collectors.toList());
        //店员id
        List<Integer> clerkIdList = storeOrderList.stream().map(StoreOrder::getClerkId).distinct().collect(Collectors.toList());

        //订单id集合
        List<Integer> orderIdList = storeOrderList.stream().map(StoreOrder::getId).distinct().collect(Collectors.toList());

        //获取门店map
        HashMap<Integer, SystemStore> systemStoreList = systemStoreService.getMapInId(storeIdList);
        //获取店员map
        HashMap<Integer, SystemStoreStaff> systemStoreStaffList = systemStoreStaffService.getMapInId(clerkIdList);
        //获取订单详情map
        HashMap<Integer, List<StoreOrderInfoVo>> orderInfoList = StoreOrderInfoService.getMapInId(orderIdList);

        //根据用户获取推广人信息
        List<Integer> userIdList = storeOrderList.stream().map(StoreOrder::getUid).distinct().collect(Collectors.toList());
        //订单用户信息
        HashMap<Integer, User> userList = userService.getMapListInUid(userIdList);

        //推广信息
        HashMap<Integer, User> mapListInUid = new HashMap<>();
        if (userIdList.size() > 0) {
            //推广人信息
            List<Integer> userServiceSpreadPeopleIdList = userService.getSpreadPeopleIdList(userIdList);
            if (userServiceSpreadPeopleIdList.size() > 0) {
                mapListInUid = userService.getMapListInUid(userServiceSpreadPeopleIdList);
            }
        }


        for (StoreOrder storeOrder : storeOrderList) {
            StoreOrderItemResponse storeOrderItemResponse = new StoreOrderItemResponse();
            BeanUtils.copyProperties(storeOrder, storeOrderItemResponse);
            String storeName = "";
            if (systemStoreList.containsKey(storeOrder.getStoreId())) {
                storeName = systemStoreList.get(storeOrder.getStoreId()).getName();
            }
            storeOrderItemResponse.setStoreName(storeName);

            String clerkName = "";
            if (systemStoreStaffList.containsKey(storeOrder.getClerkId())) {
                clerkName = systemStoreStaffList.get(storeOrder.getClerkId()).getStaffName();
            }
            storeOrderItemResponse.setProductList(orderInfoList.get(storeOrder.getId()));

            //配送方式
            storeOrderItemResponse.setShippingType(storeOrder.getShippingType());
            //订单状态
            storeOrderItemResponse.setStatus(storeOrder.getStatus());
            //订单状态描述
            storeOrderItemResponse.setStatusStr(getStatus(storeOrder));
            //使用积分
            storeOrderItemResponse.setUseIntegral(new BigDecimal(storeOrder.getUseIntegral()));
            //支付方式
            storeOrderItemResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));

            //下单用户
            storeOrderItemResponse.setOrderCreateName(storeOrder.getCreateName());

            //推广人信息
            if (!userList.isEmpty() && userList.containsKey(storeOrder.getUid()) && !mapListInUid.isEmpty()) {
                if (userList.containsKey(storeOrder.getUid()) && mapListInUid.containsKey(userList.get(storeOrder.getUid()).getUid())) {
                    storeOrderItemResponse.getSpreadInfo().setId(mapListInUid.get(userList.get(storeOrder.getUid()).getUid()).getUid());
                    storeOrderItemResponse.getSpreadInfo().setName(mapListInUid.get(userList.get(storeOrder.getUid()).getUid()).getNickname());
                }
            }

            storeOrderItemResponse.setClerkName(clerkName);
            storeOrderItemResponseArrayList.add(storeOrderItemResponse);

        }
        return storeOrderItemResponseArrayList;
    }

    /**
     * 累计消费
     *
     * @param userId Integer 用户id
     * @return UserBalanceResponse
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    public BigDecimal getSumBigDecimal(Integer userId, String date) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as pay_price").
                eq("paid", 1).
                eq("is_del", 0);
        if (null != userId) {
            queryWrapper.eq("uid", userId);
        }
        if (null != date) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        StoreOrder storeOrder = dao.selectOne(queryWrapper);
        if (null == storeOrder || null == storeOrder.getPayPrice()) {
            return BigDecimal.ZERO;
        }
        return storeOrder.getPayPrice();
    }

    /**
     * 订单列表返回map
     *
     * @param orderIdList Integer 订单id
     * @return UserBalanceResponse
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    public Map<Integer, StoreOrder> getMapInId(List<Integer> orderIdList) {
        Map<Integer, StoreOrder> map = new HashMap<>();
        if (null == orderIdList || orderIdList.size() < 1) {
            return map;
        }
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StoreOrder::getId, orderIdList);
        List<StoreOrder> orderList = dao.selectList(lambdaQueryWrapper);

        if (null == orderList || orderList.size() < 1) {
            return map;
        }

        for (StoreOrder storeOrder : orderList) {
            map.put(storeOrder.getId(), storeOrder);
        }
        return map;
    }

    /**
     * 获取订单数量
     *
     * @param userId 用户id
     * @param date   字符串月份 moth
     * @return 对应时间段的订单数量
     */
    @Override
    public int getOrderCount(Integer userId, String date) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StoreOrder::getPaid, 1)
                .eq(StoreOrder::getIsDel, 0);

        if (null != userId) {
            lambdaQueryWrapper.eq(StoreOrder::getUid, userId);
        }
        if (StringUtils.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            lambdaQueryWrapper.between(StoreOrder::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        return dao.selectCount(lambdaQueryWrapper);
    }

    /**
     * 按开始结束时间分组订单
     *
     * @param date    String 时间范围
     * @param lefTime int 截取创建时间长度
     * @return HashMap<String, Object>
     * @author Mr.Zhang
     * @since 2020-05-16
     */
    @Override
    public List<StoreOrder> getOrderGroupByDate(String date, int lefTime) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as pay_price", "left(create_time, " + lefTime + ") as orderId", "count(id) as id");
        if (StringUtils.isNotBlank(date)) {
            dateLimitUtilVo dateLimit = DateUtil.getDateLimit(date);
            queryWrapper.between("create_time", dateLimit.getStartTime(), dateLimit.getEndTime());
        }
        queryWrapper.eq("paid", 1);
        queryWrapper.groupBy("orderId").orderByAsc("orderId");
        return dao.selectList(queryWrapper);
    }

    /**
     * 退款
     *
     * @param request StoreOrderRefundRequest 退款参数
     * @return boolean
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean refund(StoreOrderRefundRequest request) {
        String lockKey = "child_order_id:" + request.getOrderId();
        RLock rLock = redisson.getLock(lockKey);
        try {
            if (!rLock.tryLock()) {
                throw new CrmebException("该订单正在退款中!");
            }
            StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(request.getOrderId());
            if (OrderStatusEnum.REJECTED_SUCCESS.getCode().equals(storeOrderInfo.getStatus())) {
                throw new CrmebException("该订单已退货退款!");
            }
            if (!Objects.equals(storeOrderInfo.getAutonomous(), 1)) {
                if (storeOrderInfo.getIsEurope() != 1 && request.getType() == 1) {
                    throw new CrmebException("云仓商品订单仅支持补偿性退款!");
                }
            }
            StoreOrder storeOrder = storeOrderService.getById(storeOrderInfo.getOrderId());


            // 获取支付渠道
            Integer type = orderUtils.getOrderPayType(storeOrder.getMerId()).getCode();
            IOrderProcess orderProcess = commonFactory.getOrderType(type);
            boolean refund = orderProcess.refund(request);

            //记录商品退款数量 author: duyb

            if (refund) {
                saveRefundNumber(storeOrderInfo.getProductId(), storeOrder.getMerId(), request.getAmount());
            }

            return refund;
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    /**
     * 记录商品退款数量
     *
     * @param productId 商品id merId 商户id amount 退款金额
     * @author duyb
     * @since 2020-10-12
     */
    private void saveRefundNumber(Integer productId, Integer merId, BigDecimal amount) {
        StoreProduct storeProduct = storeProductService.getById(productId);
        StoreProductActive storeProductActive = storeSaleAnalysisService.getOne(Wrappers.<StoreProductActive>lambdaQuery()
                .eq(StoreProductActive::getMerId, merId)
                .eq(StoreProductActive::getProductId, productId)
                .eq(StoreProductActive::getStatisticsDate, DateUtil.nowDateTimeReturnDate("yyyy-MM-dd"))
        );
        if (storeProductActive == null) {
            storeProductActive = new StoreProductActive();
            storeProductActive.setMerId(merId);
            storeProductActive.setProductId(productId);
            storeProductActive.setStoreName(storeProduct.getStoreName());
            storeProductActive.setRefundNumber(1);
            storeProductActive.setRefundAmount(amount);
            storeProductActive.setStatisticsDate(DateUtil.nowDateTimeReturnDate("yyyy-MM-dd"));
        } else {
            storeProductActive.setRefundNumber(storeProductActive.getRefundNumber() + 1);
            storeProductActive.setRefundAmount(storeProductActive.getRefundAmount().add(amount));
        }
        storeSaleAnalysisService.saveOrUpdate(storeProductActive);
    }

    /**
     * 订单详情
     *
     * @param id Integer 订单id
     * @return StoreOrderItemResponse
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    public StoreOrderInfoResponse info(Integer id) {
        StoreOrder storeOrder = getInfoException(id);
        Map<String, Object> discountInfo = new HashMap<>();
        StoreOrderInfoResponse storeOrderInfoResponse = new StoreOrderInfoResponse();
        BeanUtils.copyProperties(storeOrder, storeOrderInfoResponse);
        //优惠券名称
        StoreCouponUser storeCouponUser = Optional.ofNullable(storeCouponUserService.getById(storeOrder.getCouponId())).orElse(new StoreCouponUser());
        storeOrderInfoResponse.setCouponName(storeCouponUser.getName());
        storeOrderInfoResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));
        storeOrderInfoResponse.setStatusStr(getStatus(storeOrder));
        //下单用户
        storeOrderInfoResponse.setOrderCreateName(storeOrder.getCreateName());

        //用户信息
        User user = Optional.ofNullable(userService.getById(storeOrder.getUid())).orElse(new User());
        List<UserTagInfo> userTagInfoList = new ArrayList<>();
        if (StringUtils.isNotBlank(user.getTagIds())) {
            List<Integer> tagIdList = Stream.of(user.getTagIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());
            List<UserTag> UserTagList = userTagService.list(Wrappers.lambdaQuery(UserTag.class).in(UserTag::getId, tagIdList));
            userTagInfoList = UserTagList.stream().map(tag -> new UserTagInfo().setTagId(tag.getId()).setTagName(tag.getName())).collect(Collectors.toList());
        }
        storeOrderInfoResponse.setUserTagInfoList(userTagInfoList);
        User spread = userService.getById(user.getSpreadUid());
        if (spread != null) {
            storeOrderInfoResponse.getSpreadInfo().setId(spread.getUid());
            storeOrderInfoResponse.getSpreadInfo().setName(spread.getNickname());
        }
        storeOrderInfoResponse.setUser(user);
        storeOrderInfoResponse.setUseIntegral(BigDecimal.valueOf(Optional.ofNullable(storeOrder.getUseIntegral()).orElse(0)));
        storeOrderInfoResponse.setGainIntegral(BigDecimal.valueOf(Optional.ofNullable(storeOrder.getGainIntegral()).orElse(0)));
        storeOrderInfoResponse.setBackIntegral(BigDecimal.valueOf(Optional.ofNullable(storeOrder.getBackIntegral()).orElse(0)));

        List<StoreOrderInfoVo> orderInfoVoList = orderUtils.getOrderInfoVoList(storeOrder);
        if (CollectionUtils.isNotEmpty(orderInfoVoList)) {
            ChannelMemberLevel memberLevel = orderInfoVoList.get(0).getInfo().getMemberLevel();
            storeOrderInfoResponse.setLevelName(memberLevel != null ? memberLevel.getName() : null);
        }
        List<OrderInfoProductResponse> productList = new ArrayList<>();
        for (StoreOrderInfoVo infoVo : orderInfoVoList) {
            OrderInfoProductResponse orderInfoProductResponse = new OrderInfoProductResponse();
            StoreProduct storeProductPram = new StoreProduct();
            storeProductPram.setId(infoVo.getProductId());
            StoreProduct storeProductResponse = storeProductService.getByEntity(storeProductPram);
            if (null != storeProductResponse) {
                orderInfoProductResponse.setSuppliersId(storeProductResponse.getSuppliersId());
                orderInfoProductResponse.setSuppliersName(storeProductResponse.getSuppliersName());
                if (storeProductResponse.getIsEurope() == ProductTypeEnum.INSIDE.getCode()) {
                    orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.NO_PROCURE.getType());
                }
            }
            discountInfo = infoVo.getInfo().getDiscountInfo();
            StoreProductCartProductInfoResponse productInfo = infoVo.getInfo().getProductInfo();
            StoreProductAttrValue attrInfo = productInfo.getAttrInfo();
            orderInfoProductResponse.setStock(infoVo.getStock());
            orderInfoProductResponse.setCost(attrInfo.getCost());
            orderInfoProductResponse.setSourceCost(attrInfo.getSourceCost());
            orderInfoProductResponse.setOtPrice(attrInfo.getOtPrice());
            orderInfoProductResponse.setOrderInfoId(infoVo.getId());
            orderInfoProductResponse.setProductId(infoVo.getProductId());
            orderInfoProductResponse.setCartNum(infoVo.getNum());
            orderInfoProductResponse.setImage(attrInfo.getImage());
            orderInfoProductResponse.setStoreName(productInfo.getStoreName());
            orderInfoProductResponse.setChildOrderNumber(infoVo.getChildOrderNumber());
            orderInfoProductResponse.setStatus(infoVo.getStatus());
            orderInfoProductResponse.setProductPaidPrice(attrInfo.getProductPaidPrice());
            orderInfoProductResponse.setPaidPrice(attrInfo.getPaidPrice());
            orderInfoProductResponse.setDeductionPrice(attrInfo.getDeductionPrice());
            orderInfoProductResponse.setUseIntegral(attrInfo.getUseIntegral());
            orderInfoProductResponse.setActivityProductPrice(attrInfo.getActivityProductPrice());
//            orderInfoProductResponse.setIsEurope(infoVo.getInfo().getProductInfo().getIsEurope());
            orderInfoProductResponse.setIsEurope(Objects.nonNull(infoVo.getIsEurope()) ? infoVo.getIsEurope() : infoVo.getInfo().getProductInfo().getIsEurope());
            BigDecimal subTotalPrice = attrInfo.getSubTotalPrice() == null ? attrInfo.getPrice().add(attrInfo.getTaxPrice() == null ? BigDecimal.ZERO : attrInfo.getTaxPrice().add(attrInfo.getSecondPrice() == null ? BigDecimal.ZERO : attrInfo.getSecondPrice())) : attrInfo.getSubTotalPrice();
            orderInfoProductResponse.setSubTotalPrice(subTotalPrice);
            if (attrInfo.getInitialPaidPrice() != null) {
                orderInfoProductResponse.setChangePrice(attrInfo.getPaidPrice().subtract(attrInfo.getInitialPaidPrice()));
            }
            //橙子商品设置keyword为itemCode
            String keyword = productInfo.getKeyword();
            if (ProductTypeEnum.ORANGE.getCode().equals(infoVo.getInfo().getProductInfo().getIsEurope())) {
                StoreProductAttrResult result = storeProductAttrResultService.getByProductId(infoVo.getInfo().getProductId());
                JSONArray jsonArray = JSONArray.parseArray(result.getResult());
                for (Object o : jsonArray) {
                    JSONObject jsonObject = JSONObject.parseObject(o.toString());
                    if (Objects.equals(jsonObject.get("sourceSkuId"), attrInfo.getSourceSkuId())) {
                        keyword = (String) jsonObject.get("skuCode");
                    }
                }
            }
            orderInfoProductResponse.setKeyword(keyword);
            orderInfoProductResponse.setSuk(attrInfo.getSuk());
            orderInfoProductResponse.setTempId(productInfo.getTempId());
            orderInfoProductResponse.setTempName(StockAreaTempEnum.getByTempId(productInfo.getTempId()).getStockAreaName());
            orderInfoProductResponse.setPrice(attrInfo.getPrice());
            orderInfoProductResponse.setTotalPrice(attrInfo.getPrice().multiply(new BigDecimal(infoVo.getInfo().getCartNum())));
            OrderInfoDelivery delivery = null;
            if (!BooleanUtils.isTrue(infoVo.getIsVirtual())) {
                delivery = orderInfoDeliveryService.selectDeliveryByOrderInfoId(infoVo.getId());
                orderInfoProductResponse.setDelivery(delivery);
            }
            orderInfoProductResponse.setUserDelivery(orderInfoDeliveryService.getOne(Wrappers.<OrderInfoDelivery>lambdaQuery()
                    .eq(OrderInfoDelivery::getOrderInfoId, infoVo.getId()).eq(OrderInfoDelivery::getChannel, 5).orderByDesc(OrderInfoDelivery::getId).last("LIMIT 1")));
            if (Objects.equals(infoVo.getIsEurope(), ProductTypeEnum.INSIDE.getCode())) {
                orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.NO_PROCURE.getType());
            } else if (Objects.equals(infoVo.getAutonomous(), 1)) {
                orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.AUTO_PROCURE.getType());
            } else {
                if (BooleanUtils.isTrue(infoVo.getIsVirtual())) {
                    orderInfoProductResponse.setProcureStatus(ProcureStatusEnum.FOR_PROCURE.getType());
                } else {
                    List<PurchaseGoods> purchaseGoodsList = purchaseGoodsService.list(Wrappers.lambdaQuery(PurchaseGoods.class).eq(PurchaseGoods::getPushStatus, 1).eq(PurchaseGoods::getPushType, 0).eq(PurchaseGoods::getStoreOrderInfoId, infoVo.getId()));
                    orderInfoProductResponse.setProcureStatus((CollectionUtils.isEmpty(purchaseGoodsList) && delivery == null) ? ProcureStatusEnum.FOR_PROCURE.getType() : ProcureStatusEnum.PROCURE.getType());
                    List<String> deliveryOrderNoList = purchaseGoodsList.stream().map(PurchaseGoods::getChannelOrderSn).distinct().collect(Collectors.toList());
                    orderInfoProductResponse.setDeliveryOrderNoList(deliveryOrderNoList);
                }
            }
            orderInfoProductResponse.setOrderCode(Integer.toString(Integer.parseInt(infoVo.getOrderId() + "" + infoVo.getId()), 36).toUpperCase());
            orderInfoProductResponse.setDeliveryAddress(infoVo.getDeliveryAddress());
            orderInfoProductResponse.setSecondPrice(attrInfo.getSecondPrice());
            orderInfoProductResponse.setFirstPrice(attrInfo.getFirstPrice());
            orderInfoProductResponse.setTaxPrice(attrInfo.getTaxPrice());
            orderInfoProductResponse.setBrandName(productInfo.getBrandName());
            orderInfoProductResponse.setAbnormal(infoVo.getAbnormal());
            orderInfoProductResponse.setExchangeRate(infoVo.getExchangeRate());
            //退款信息
            orderInfoProductResponse.setRefundReasonTime(infoVo.getRefundReasonTime());
            List<StoreOrderStatus> storeOrderStatusList = storeOrderStatusService.list(Wrappers.lambdaQuery(StoreOrderStatus.class).eq(StoreOrderStatus::getChangeType, Constants.ORDER_LOG_REFUND_PRICE)
                    .eq(StoreOrderStatus::getOrderNumber, infoVo.getChildOrderNumber()).notLike(StoreOrderStatus::getChangeMessage, "失败").orderByAsc(StoreOrderStatus::getCreateTime));
            if (CollectionUtils.isNotEmpty(storeOrderStatusList)) {
                List<RefundInfo> refundInfoList = storeOrderStatusList.stream().map(e -> new RefundInfo().setRefundPrice(new BigDecimal(e.getChangeMessage().substring(e.getChangeMessage().indexOf("用户") + 2, e.getChangeMessage().indexOf("元"))))
                        .setRefundTime(e.getCreateTime()).setRefundType(e.getChangeMessage().contains("退货退款") ? 2 : 1)).collect(Collectors.toList());
                orderInfoProductResponse.setRefundInfoList(refundInfoList);
            }
            //加价计算方式
            String calculation = priceUtil.getCalculation(productInfo.getMarkupType(), productInfo.getPriceChange(), null);
            int count = storeOrderStatusService.count(Wrappers.lambdaQuery(StoreOrderStatus.class).eq(StoreOrderStatus::getChangeType, Constants.ORDER_UPDATE_PRICE).eq(StoreOrderStatus::getOid, id)
                    .eq(StoreOrderStatus::getOrderNumber, infoVo.getChildOrderNumber()));
            if (count > 0) {
                calculation = "订单提交后修改价格";
            }
            orderInfoProductResponse.setCalculation(calculation);
            orderInfoProductResponse.setCouponPrice(infoVo.getCouponPrice());
            orderInfoProductResponse.setNote(storeOrderStatusService.getNote(infoVo.getOrderId(), infoVo.getChildOrderNumber(), Constants.ORDER_MERCHANT_NOTE));
            orderInfoProductResponse.setAutonomous(infoVo.getAutonomous());
            orderInfoProductResponse.setVipReducePrice(infoVo.getVipReducePrice());
            orderInfoProductResponse.setActivityId(infoVo.getActivityId());
            if (infoVo.getRefundStatus() != null && infoVo.getStatus() != null) {
                if (infoVo.getRefundStatus() == 1 || infoVo.getStatus() == -1) {
                    StoreOrderRefundApply refundApply = storeOrderRefundApplyService.getOne(Wrappers.<StoreOrderRefundApply>lambdaQuery().eq(StoreOrderRefundApply::getInfoId, infoVo.getId())
                            .orderByDesc(StoreOrderRefundApply::getId).last("LIMIT 1"));
                    orderInfoProductResponse.setStoreOrderRefundApply(refundApply);
                }
            }
            productList.add(orderInfoProductResponse);
        }
        //增加商户类型
        ChannelMerchant channelMerchant = channelMerchantService.getById(storeOrderInfoResponse.getMerId());
        if (Objects.nonNull(channelMerchant)) {
            storeOrderInfoResponse.setAppletType(channelMerchant.getAppletType());
        }
        storeOrderInfoResponse.setProductList(productList);
        //统计活动优惠总价
        storeOrderInfoResponse.setActivityTotalDiscount(productList.stream()
                .map(OrderInfoProductResponse::getActivityProductPrice)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
        //满减送信息
        storeOrderInfoResponse.setDiscountInfo(discountInfo);
        return storeOrderInfoResponse;
    }

    /**
     * 发送货物
     *
     * @param request StoreOrderSendRequest 发货参数
     * @return boolean
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public boolean send(StoreOrderSendRequest request) {
        try {
            //订单信息
            StoreOrder storeOrder = getInfoException(request.getId());

            switch (request.getType()) {
                case "1":
                    express(request, storeOrder);
                    break;
                case "2":
                    delivery(request, storeOrder);
                    break;
                case "3":
                    virtual(request, storeOrder);
                    break;
                default:
                    throw new CrmebException("类型错误");
            }

            //短信发送

            return true;
        } catch (Exception e) {
            //发货失败！
            throw new CrmebException(e.getMessage());
        }
    }

    /**
     * 备注订单
     *
     * @param id   integer id
     * @param mark String 备注
     * @return boolean
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public boolean mark(Integer id, String mark) {
        StoreOrder storeOrder = getInfoException(id);
        storeOrder.setRemark(mark);
        return updateById(storeOrder);
    }

    /**
     * 拒绝退款
     *
     * @param id     integer id
     * @param reason String 原因
     * @return boolean
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public boolean refundRefuse(Integer id, String reason) {
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (null == storeOrderInfo) {
            throw new CrmebException("没有找到订单信息");
        }
        if (storeOrderInfo.getRefundStatus() != 1 && storeOrderInfo.getStatus() != -1) {
            throw new CrmebException("该订单不是申请退款状态");
        }
        StoreOrderRefundApply refundApply = storeOrderRefundApplyService.getOne(Wrappers.<StoreOrderRefundApply>lambdaQuery()
                .eq(StoreOrderRefundApply::getInfoId, id)
                .orderByDesc(StoreOrderRefundApply::getId).last("LIMIT 1"));
        if (null == refundApply) {
            throw new CrmebException("订单申请退款记录不存在");
        }
        if (refundApply.getProcessType() != null) {
            throw new CrmebException("该订单已处理");
        }
        refundApply.setProcessType(2);
        refundApply.setProcessTime(new Date());
        refundApply.setRefundRefuseReason(reason);
        storeOrderRefundApplyService.updateById(refundApply);

        storeOrderInfo.setRefundReason(reason);
        storeOrderInfo.setRefundStatus(0);
        storeOrderInfo.setStatus(refundApply.getOldStatus());
        storeOrderInfoService.updateById(storeOrderInfo);
        storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_LOG_REFUND_REFUSE, "拒绝退款");

        //TODO 模板消息通知

        return true;
    }

    /**
     * 查询单条
     *
     * @param storeOrder StoreOrder 订单参数
     * @return StoreOrder
     * @author Mr.Zhang
     * @since 2020-05-28
     */
    @Override
    public StoreOrder getInfoByEntity(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.setEntity(storeOrder);
        return dao.selectOne(lambdaQueryWrapper);
    }

    /**
     * 根据条件获取
     *
     * @param storeOrder 订单条件
     * @return 结果
     */
    @Override
    public StoreOrder getInfoJustOrderInfo(StoreOrder storeOrder) {
        LambdaQueryWrapper<StoreOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (null != storeOrder.getUnique()) {
            lambdaQueryWrapper.or().eq(StoreOrder::getOrderId, storeOrder.getUnique())
                    .or().eq(StoreOrder::getUnique, storeOrder.getUnique());
        }
        if (null != storeOrder.getUid()) {
            lambdaQueryWrapper.eq(StoreOrder::getUid, storeOrder.getUid());
        }
        if (null != storeOrder.getIsDel()) {
            lambdaQueryWrapper.eq(StoreOrder::getIsDel, storeOrder.getIsDel());
        }
        return dao.selectOne(lambdaQueryWrapper);
    }

    @Override
    public LogisticsResultVo getLogisticsInfo(Integer id) {
        StoreOrder info = getById(id);
        if (StringUtils.isBlank(info.getDeliveryId())) {
            //没有查询到快递信息
            throw new CrmebException("没有查询到快递信息");
        }

        return logisticService.info(info.getDeliveryId(), null);
    }

    /**
     * 根据用户id获取订单数据
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public RetailShopOrderDataResponse getOrderDataByUserId(Integer userId) {
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(pay_price) as totalPrice, count(id) as id");
        queryWrapper.ge("paid", 1);
        queryWrapper.ge("refund_status", 0);
        queryWrapper.eq("uid", userId);
        queryWrapper.groupBy("uid");
        StoreOrder storeOrder = dao.selectOne(queryWrapper);
        RetailShopOrderDataResponse rop = new RetailShopOrderDataResponse();
        if (null != storeOrder) {
            rop.setOrderCount(storeOrder.getId()); // id=借变量传递数据
            rop.setOrderPrice(storeOrder.getTotalPrice());
        }

        return rop;
    }

    /**
     * 根据用户id集合获取对应订单，分销中使用
     *
     * @param ids 用户id集合
     * @return 对应用户订单集合
     */
    @Override
    public List<StoreOrder> getOrderByUserIdsForRetailShop(List<Integer> ids) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.in(StoreOrder::getUid, ids);
        lqw.ge(StoreOrder::getPaid, 1);
        lqw.ge(StoreOrder::getRefundStatus, 0);
        return dao.selectList(lqw);
    }

    /**
     * 订单 top 查询参数
     *
     * @param status 状态参数
     * @return 订单查询结果
     */
    @Override
    public List<StoreOrder> getTopDataUtil(int status, int userId) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        statusApiByWhere(lqw, status);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getUid, userId);
        return dao.selectList(lqw);
    }


    @Override
    public List<String> queryOrderIds(Date startTime) {
        QueryWrapper<StoreOrder> wapper = new QueryWrapper<>();
        wapper.select("order_id");
        wapper.eq("paid", 1);
        wapper.eq("refund_status", 0);
        wapper.eq("is_del", 0);
        wapper.gt("pay_time", startTime);
        wapper.eq("push_status", 0);
        List<Object> list = dao.selectObjs(wapper);
        return list == null ? Lists.newArrayList() : list.stream().map(o -> o.toString()).collect(Collectors.toList());
    }

    @Override
    public void push(TmallStoreOrderRequest order, List<TmallOrderInfoRequest> orderInfoRequestList) {
        StoreOrder storeOrder = new StoreOrder();
        BeanUtils.copyProperties(order, storeOrder);
        storeOrder.setPayType("tmall");
        storeOrder.setUid(293);
        storeOrder.setIsChannel(1);
        //订单来源 1 寻物 2天猫
        storeOrder.setSource(2);
        storeOrder.setMark("");
        storeOrder.setPaid(true);
        storeOrder.setStatus(Constants.ORDER_STATUS_H5_NOT_SHIPPED);
        storeOrder.setUnique(DigestUtils.md5Hex(order.getOrderId()));
        storeOrder.setAreaType(AreaTypeEnum.HK.getType());
        dao.insert(storeOrder);

        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (TmallOrderInfoRequest tmallOrderInfo : orderInfoRequestList) {
            StoreOrderInfo soInfo = new StoreOrderInfo();
            StoreProduct storeProduct = storeProductService.getById(tmallOrderInfo.getProductId());
            if (null != storeProduct) {
                tmallOrderInfo.getProductInfo().setImage(storeProduct.getImage());
                tmallOrderInfo.getProductInfo().setKeyword(storeProduct.getKeyword());
                soInfo.setIsEurope(storeProduct.getIsEurope());
            }
            soInfo.setOrderId(storeOrder.getId());
            soInfo.setProductId(tmallOrderInfo.getProductId());
            soInfo.setInfo(JSON.toJSON(tmallOrderInfo).toString());
            soInfo.setUnique(DigestUtils.md5Hex(tmallOrderInfo.toString()));
            storeOrderInfos.add(soInfo);
        }
        // 保存购物车商品详情
        boolean saveBatchOrderInfosResult = storeOrderInfoService.saveOrderInfos(storeOrderInfos);
        if (!saveBatchOrderInfosResult) {
            throw new CrmebException("订单生成失败");
        }

        //天猫订单记录增加
        String message = "同步天猫订单";
        storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_TMALL_ORDER, message);

        Object validateCode = redisUtil.get(SmsConstants.SMS_VALIDATE_PHONE + ("15158117076"));
        if (null == validateCode) {
            SendSmsVo sendSmsVo = new SendSmsVo();
            sendSmsVo.setMobiles("15158117076");
            sendSmsVo.setSendEnable(sendenable);
            sendSmsVo.setTemplate(SmsConstants.SMS_ORDER_TEMPLATEID);
            smsService.sendMessage(sendSmsVo);
        }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////// 以下为自定义方法

    /** 退款扣除积分/余额
     * @param request StoreOrderRefundRequest 退款参数
     * @author Mr.Zhang
     * @since 2020-06-10
     */
//    private void subtractBill(StoreOrderRefundRequest request, String category, String type, String foundsType) {
//        try{
//            FundsMonitorSearchRequest fundsMonitorSearchRequest = new FundsMonitorSearchRequest();
//            fundsMonitorSearchRequest.setCategory(category);
//            fundsMonitorSearchRequest.setType(type);
//            fundsMonitorSearchRequest.setLinkId(request.getOrderId().toString());
//            fundsMonitorSearchRequest.setPm(1);
//
//            PageParamRequest pageParamRequest = new PageParamRequest();
//            pageParamRequest.setLimit(Constants.EXPORT_MAX_LIMIT);
//            List<UserBill> list = userBillService.getList(fundsMonitorSearchRequest, pageParamRequest);
//
//            if(null == list || list.size() < 1){
//                return;
//            }
//
//            for (UserBill userBill : list) {
//                User user = userService.getById(userBill.getUid());
//                if(null == user){
//                    continue;
//                }
//                BigDecimal price;
//                if(category.equals(Constants.USER_BILL_CATEGORY_INTEGRAL)){
//                    price = user.getIntegral();
//                }else{
//                    price = user.getBrokeragePrice();
//                }
//
//                if(userBill.getNumber().compareTo(price) > 0){
//                    userBill.setNumber(price);
//                    //更新佣金
//                    UserOperateFundsRequest userOperateFundsRequest = new UserOperateFundsRequest();
//                    userOperateFundsRequest.setUid(user.getUid());
//                    userOperateFundsRequest.setValue(request.getAmount());
//                    userOperateFundsRequest.setFoundsType(foundsType);
//                    userOperateFundsRequest.setType(0);
//                    userService.updateFounds(userOperateFundsRequest, false); //更新佣金/积分
//                    if(category.equals(Constants.USER_BILL_CATEGORY_INTEGRAL)){
//                        userBillService.saveRefundIntegralBill(request, user);
//                    }else{
//                        userBillService.saveRefundBrokeragePriceBill(request, user);
//                    }
//                }
//            }
//        }catch (Exception e){
//            throw new CrmebException("更新退款佣金/积分失败");
//        }
//    }

    /**
     * 发货
     *
     * @param id Integer id
     * @return Boolean
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    public StoreOrder getInfoException(Integer id) {
        StoreOrder info = getById(id);
        if (null == info) {
            throw new CrmebException("没有找到订单信息");
        }
        return info;
    }


    /**
     * 快递
     *
     * @param request    StoreOrderSendRequest 发货参数
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    private void express(StoreOrderSendRequest request, StoreOrder storeOrder) {
        try {
            if (!storeOrder.getStatus().equals(Constants.ORDER_STATUS_H5_SPIKE) && !storeOrder.getStatus().equals(Constants.ORDER_STATUS_H5_NOT_SHIPPED)) {
                throw new CrmebException("当前订单状态无法发货");
            }
            if (!Objects.equals(request.getChannel(), 1) || !Objects.equals(request.getLogisticsType(), 0)) {
                throw new CrmebException("操作方式异常!");
            }
            //快递信息
            Express express;
            if (request.getName().equals("同城配送")){
                express = new Express();
            } else {
                express = expressService.info(Integer.parseInt(request.getExpressId()));
            }
            StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(request.getOrderInfoId());
            if (Constants.ORDER_STATUS_H5_NOT_SHIPPED == storeOrderInfo.getStatus()) {
                storeOrderInfo.setStatus(Constants.ORDER_STATUS_H5_SPIKE);
                storeOrderInfoService.updateById(storeOrderInfo);
                if (!storeOrder.getStatus().equals(Constants.ORDER_STATUS_H5_SPIKE)) {
                    storeOrder.setStatus(Constants.ORDER_STATUS_H5_SPIKE);
                    this.updateById(storeOrder);
                }
            }

            StoreCartResponse response = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            //物流信息列表
            List<OrderInfoDelivery> deliveryList = orderInfoDeliveryService.list(Wrappers.<OrderInfoDelivery>lambdaQuery().eq(OrderInfoDelivery::getOrderInfoId, request.getOrderInfoId()).ne(OrderInfoDelivery::getIsExchange, 1).or().isNull(OrderInfoDelivery::getIsExchange));
            String message = (deliveryList.size() < 1 ? Constants.ORDER_LOG_MESSAGE_EXPRESS : Constants.ORDER_LOG_ADD_MESSAGE_EXPRESS)
                    .replace("{storeName}", response.getProductInfo().getStoreName()).replace("{suk}", response.getProductInfo().getAttrInfo().getSuk())
                    .replace("{channel}", "商户");
            if (request.getName().equals("同城配送")){
                message = message.replace("{deliveryName}", request.getName()).replace("{deliveryCode}", "无");
            } else {
                message = message.replace("{deliveryName}", express.getName()).replace("{deliveryCode}", request.getExpressCode());
            }
            storeOrderStatusService.createLog(request.getId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_LOG_EXPRESS, message);
            //新增物流信息
            OrderInfoDeliveryRequest delivery = new OrderInfoDeliveryRequest();
            delivery.setOrderInfoId(request.getOrderInfoId());
            delivery.setDeliveryCompany(express.getName());
            delivery.setDeliveryNumber(request.getExpressCode());
            delivery.setName(request.getName());
            delivery.setDeliveryCode(express.getCode());
            delivery.setPhone(request.getPhone());
            delivery.setExpressId(StringUtils.isBlank(request.getExpressId()) ? null : Integer.parseInt(request.getExpressId()));
            delivery.setLogisticsStage(request.getLogisticsStage());
            if (!Objects.isNull(request.getLevel())) {
                delivery.setLevel(request.getLevel());
            }
            delivery.setChannel(request.getChannel());
            orderInfoDeliveryService.addDelivery(delivery);

            // 发货消息推送
            List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery()
                    .eq(StoreOrderInfo::getOrderId, storeOrder.getId())
            );
            List<Integer> infoIds = storeOrderInfos.stream().map(StoreOrderInfo::getId).collect(Collectors.toList());
            List<OrderInfoDelivery> orderInfoDeliverys = orderInfoDeliveryService.list(Wrappers.<OrderInfoDelivery>lambdaQuery()
                    .in(OrderInfoDelivery::getOrderInfoId, infoIds)
                    .last("GROUP BY order_info_id")
            );
            if (infoIds.size() == orderInfoDeliverys.size()) {
                List<OrderInfoDelivery> orderInfoDeliverys2 = orderInfoDeliveryService.list(Wrappers.<OrderInfoDelivery>lambdaQuery()
                        .in(OrderInfoDelivery::getOrderInfoId, infoIds)
                );
                OutStoreOrderResponse outStoreOrderResponse = new OutStoreOrderResponse();
                outStoreOrderResponse.setOrderId(storeOrder.getOrderId());
                outStoreOrderResponse.setOrderInfoDeliverys(orderInfoDeliverys2);

                //海带云发货
                if (27 == storeOrder.getMerId()) {
                    deliverGoods(storeOrder.getOrderId().split("OT")[1], express.getCode(), request.getExpressCode());
                } else {
                    sendBackOrder(storeOrder.getMerId(), outStoreOrderResponse, storeOrder.getBackCount());
                }
            }

        } catch (Exception e) {
            throw new CrmebException("快递发货失败！" + e.getMessage());
        }

    }

    /**
     * 订单发货通知
     *
     * @param @param merId
     * @param @param OrderInfoDeliverys
     * @return void
     * @throws
     * @Description:
     * @author daigb
     */
    @Override
    public void sendBackOrder(Integer merId, OutStoreOrderResponse outStoreOrderResponse, Integer backCount) {
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
        if (null == channelMerchant || StringUtils.isEmpty(channelMerchant.getBackUrl())) {
            log.info("--------------- 推送订单发货通知, 该商户不存在或者未配置回调url: {} ---------------", channelMerchant);
            return;
        }
        // 加密签名
        Long millis = System.currentTimeMillis();
        String token = ProductUtil.getSign(millis.toString(), channelMerchant.getMerchantNo(), channelMerchant.getMerchantSecret());
        outStoreOrderResponse.setMillis(millis);
        outStoreOrderResponse.setToken(token);

        backCount = null == backCount ? 1 : backCount + 1;
        Boolean backStatus = false;
        try {
            String result = restTemplateUtil.postStringData(channelMerchant.getBackUrl(), JSON.toJSONString(outStoreOrderResponse));
            log.info("--------------- 推送订单发货通知, 商户号: {}, 订单号: {}, 物流列表: {}, 回调地址: {}, 商户返回: {} ---------------", channelMerchant.getMerchantNo(), outStoreOrderResponse.getOrderId(), JSON.toJSONString(outStoreOrderResponse.getOrderInfoDeliverys()), channelMerchant.getBackUrl(), result);

            if (StringUtil.isNotEmpty(result)) {
                String backCode = JSONObject.parseObject(result).get("code").toString();
                if ("200".equals(backCode)) {
                    backStatus = true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.update(Wrappers.<StoreOrder>lambdaUpdate()
                .eq(StoreOrder::getOrderId, outStoreOrderResponse.getOrderId())
                .set(StoreOrder::getBackCount, backCount)
                .set(StoreOrder::getBackStatus, backStatus)
        );

    }

    @Override
    public List<MerStoreOrderExcelVo> getExportList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
//        storeOrderService.getStoreOrderListRequest(request,systemAdmin);
        getStoreOrderListRequest(request);
        request.setRequestSource("MER");
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreOrderInfo> childOrderList = dao.selectChildOrderListByUnionQuery(request);
//        List<StoreOrderProduct> storeOrderList = dao.getExportList(request);
        if (childOrderList != null && childOrderList.size() > 0) {
            List<MerStoreOrderExcelVo> list = formatStoreOrderExcelVo(childOrderList);
            return list;
        }
        return new ArrayList<MerStoreOrderExcelVo>();
    }

    @Override
    public boolean confirmChildOrder(Integer id, String remark) {
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (storeOrderInfo == null) {
            throw new CrmebException("该子订单不存在");
        }
        if (storeOrderInfo.getAbnormal() == 1) {
            throw new CrmebException("该订单为异常订单");
        }
        if (!storeOrderInfo.getStatus().equals(OrderStatusEnum.CONFIRM.getCode())) {
            throw new CrmebException("该子订单状态不是待确认状态");
        }
        if (storeOrderInfo.getIsEurope() != 1) {
            throw new CrmebException("商户只能确认自建商品订单");
        }
        storeOrderInfo.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
        String message = Constants.ORDER_LOG_MESSAGE_CONFIRM_SUCCESS;
        if (StringUtils.isNotBlank(remark)) {
            message = message + ",备注：" + remark;
        }
        boolean b = storeOrderInfoService.updateById(storeOrderInfo);
        if (b) {
            //确认订单记录备注
            storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_CONFIRM_SUCCESS, message);
            //查询主订单状态
            StoreOrder storeOrder = getById(storeOrderInfo.getOrderId());
            if (storeOrder.getStatus().equals(OrderStatusEnum.CONFIRM.getCode())) {
                storeOrder.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                updateById(storeOrder);
            }
        }
        return b;
    }

    @Override
    public boolean updateUserAddress(UpdateUserAddressRequest request) {
        StoreOrder storeOrder = getById(request.getId());
        if (null == storeOrder) {
            throw new CrmebException("该订单不存在");
        }
        if (!storeOrder.getStatus().equals(OrderStatusEnum.CONFIRM.getCode()) && !storeOrder.getStatus().equals(OrderStatusEnum.UNPAID.getCode()) && !storeOrder.getStatus().equals(OrderStatusEnum.VERIFY.getCode())) {
            throw new CrmebException("只有待审核,未支付,待确认的订单可以修改");
        }
        if (storeOrder.getPickingId() > 0 && !request.getAreaType().equals(storeOrder.getAreaType())) {
            throw new CrmebException("区域类型不正确");
        }
        //2c可以修改其他地区的地址，2b只能改为当前地区
        ChannelMerchant channelMerchant = channelMerchantService.getById(storeOrder.getMerId());
        if (Objects.equals(channelMerchant.getAppletType(), 0) && !request.getAreaType().equals(storeOrder.getAreaType())) {
            throw new CrmebException("区域类型不正确");
        }
        if (StringUtils.isNotBlank(request.getIdCard())) {
        	idCardUtils.checkIdCard(request.getRealName(), request.getIdCard());
            storeOrder.setIdCard(request.getIdCard());
        }
        if (storeOrder.getStatus().equals(OrderStatusEnum.CONFIRM.getCode())) {
            boolean flag = false;
            //查询订单商品来源
            List<StoreOrderInfo> list = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, request.getId()));
            for (StoreOrderInfo storeOrderInfo : list) {
                if (storeOrderInfo.getIsEurope() != 1) {
                    flag = true;
                }
            }
            if (flag) {
                throw new CrmebException("订单中有供应商商品,请联系平台修改");
            }
        }
        BeanUtils.copyProperties(request, storeOrder, "idCard");
        storeOrder.setUserAddress(request.getProvince() + request.getCity() + request.getDistrict() + request.getDetail());
        boolean b = updateById(storeOrder);
        if (b) {
            storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), "update_address", "后台修改地址");
        }
        return b;
    }

    /**
     * 修改订单商品成交价
     *
     * @param id
     * @param price
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object updateOrderPrice(Integer id, BigDecimal price) {
        if (price.compareTo(BigDecimal.ZERO) < 0) {
            throw new CrmebException("价格不能小于0");
        }
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (null == storeOrderInfo) {
            throw new CrmebException("该订单不存在");
        }
        if (!storeOrderInfo.getStatus().equals(OrderStatusEnum.UNPAID.getCode())) {
            throw new CrmebException("只有待付款的订单能修改价格");
        }
        StoreOrder storeOrder = getById(storeOrderInfo.getOrderId());
        StoreCartResponse response = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
        StoreProductAttrValue attrInfo = response.getProductInfo().getAttrInfo();
        //修改之前价格
        BigDecimal paidPrice = attrInfo.getPaidPrice();
        if (price.compareTo(paidPrice) == 0) {
            throw new CrmebException("输入金额与当前付款金额相同!");
        }
        //保存原始价格
        if (attrInfo.getInitialPaidPrice() == null) {
            attrInfo.setInitialPaidPrice(paidPrice);
        }
        //商家改价
        attrInfo.setPaidPrice(price);
        //变化价格
        BigDecimal changePrice = paidPrice.subtract(price);
        attrInfo.setSubTotalPrice(attrInfo.getSubTotalPrice().subtract(changePrice));
        //商品售价实际支付金额
        BigDecimal productPaidPrice = price.subtract(attrInfo.getTaxAndSecondPrice());
        attrInfo.setProductPaidPrice(productPaidPrice.compareTo(BigDecimal.ZERO) > 0 ? productPaidPrice : BigDecimal.ZERO);
        String info = JSON.toJSONString(response);
        storeOrderInfo.setPayPrice(price);
        storeOrderInfo.setInfo(info);
        //处理子订单
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrderInfo.getOrderId()).ne(StoreOrderInfo::getId, id));
        storeOrderInfoList.add(storeOrderInfo);
        //修改总订单金额 （支付金额）
        storeOrder.setPayPrice(storeOrder.getPayPrice().subtract(changePrice));
        //生成新的主订单 ，删除旧的
        StoreOrder newStoreOrder = new StoreOrder();
        BeanUtils.copyProperties(storeOrder, newStoreOrder, "id");
        newStoreOrder.setOrderId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));
        removeById(storeOrder);
        save(newStoreOrder);
        log.info("-----------删除订单：{},新生成订单：{}-------------", storeOrder.getOrderId(), newStoreOrder.getOrderId());
        storeOrderInfoList.forEach(e -> e.setOrderId(newStoreOrder.getId()));
        storeOrderInfoService.saveOrUpdateBatch(storeOrderInfoList);
        //修改操作记录
        storeOrderStatusService.update(Wrappers.lambdaUpdate(StoreOrderStatus.class).set(StoreOrderStatus::getOid, newStoreOrder.getId()).eq(StoreOrderStatus::getOid, storeOrder.getId()));
        storeOrderStatusService.update(Wrappers.lambdaUpdate(StoreOrderStatus.class).set(StoreOrderStatus::getOrderNumber, newStoreOrder.getOrderId()).eq(StoreOrderStatus::getOrderNumber, storeOrder.getOrderId()).eq(StoreOrderStatus::getOid, newStoreOrder.getId()));
        storeOrderStatusService.createLog(newStoreOrder.getId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_UPDATE_PRICE, "付款金额由" + paidPrice + "元改为" + price + "元");
        //修改用户账单
        userBillService.update(Wrappers.lambdaUpdate(UserBill.class).set(UserBill::getLinkId, newStoreOrder.getId()).eq(UserBill::getLinkId, storeOrder.getId().toString()).eq(UserBill::getType, "deduction"));
        return newStoreOrder.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancel(Integer id) {
        StoreOrder storeOrder = getById(id);
        if (null == storeOrder) {
            throw new CrmebException("没有找到相关订单信息!");
        }
        if (!storeOrder.getStatus().equals(OrderStatusEnum.UNPAID.getCode()) && !storeOrder.getStatus().equals(OrderStatusEnum.VERIFY.getCode())) {
            throw new CrmebException("订单状态异常");
        }
        storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), "cancel_order", "商户取消订单");
        //取消订单返还
        storeOrderService.cancelUserIntegral(storeOrder, userService.getById(storeOrder.getUid()), "商户取消订单");
        //取消前状态
        Integer status = storeOrder.getStatus();
        //已取消
        storeOrder.setStatus(OrderStatusEnum.CANCEL.getCode());
        //回滚使用积分
        if (storeOrder.getUseIntegral() > 0) {
            storeOrder.setBackIntegral(storeOrder.getUseIntegral());
            storeOrder.setUseIntegral(0);
        }
        boolean update = updateById(storeOrder);
        //回滚优惠券
        storeCouponUserService.rollbackByCancelOrder(storeOrder);
        if (update && !Objects.equals(status, OrderStatusEnum.VERIFY.getCode())) {
            //取消子订单
            storeOrderInfoService.update(Wrappers.lambdaUpdate(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrder.getId())
                    .set(StoreOrderInfo::getStatus, OrderStatusEnum.CANCEL.getCode()));
            storeOrderTaskService.rollbackStock(storeOrder);
        }
        return update;
    }

    /**
     * 核对校验码
     *
     * @param id
     * @param verifyCode
     * @return
     */
    @Override
    public boolean checkCode(Integer id, String verifyCode) {
        if (StringUtils.isBlank(verifyCode)) {
            throw new CrmebException("检验码不能为空");
        }
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (null == storeOrderInfo) {
            throw new CrmebException("没有找到相关订单信息!");
        }
        if (!storeOrderInfo.getStatus().equals(OrderStatusEnum.SHIPPED.getCode()) && !storeOrderInfo.getStatus().equals(OrderStatusEnum.NOT_SHIPPED.getCode())) {
            throw new CrmebException("订单状态异常");
        }
        if (!verifyCode.equals(storeOrderInfo.getVerifyCode())) {
            throw new CrmebException("检验码错误");
        }
        storeOrderInfo.setStatus(OrderStatusEnum.COMPLETE.getCode());
        boolean b = storeOrderInfoService.updateById(storeOrderInfo);
        if (b) {
            storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), "check_code", "核验验证码:" + verifyCode + "核验成功");
            orderUtils.updateOrderStatus(storeOrderInfo.getOrderId());
            return true;
        } else {
            return false;
        }
    }

    /**
     * 扣除可用余额
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deductAccount(Integer id, Integer merId) {
        StoreOrder storeOrder = getById(id);
        if (null == storeOrder) {
            throw new CrmebException("没有找到相关订单信息!");
        }
        if (storeOrder.getStatus() != 6 && storeOrder.getAbnormal() != 1) {
            throw new CrmebException("订单状态异常!");
        }
        Boolean payType = orderUtils.getPayType(storeOrder.getPayType());
        //查询订单扣除金额
        BigDecimal cost = BigDecimal.ZERO;
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(Wrappers.<StoreOrderInfo>lambdaQuery().eq(StoreOrderInfo::getOrderId, storeOrder.getId()).eq(StoreOrderInfo::getAbnormal, 1));
        for (StoreOrderInfo storeOrderInfo : orderInfoList) {
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreProductAttrValue attrInfo = storeCartResponse.getProductInfo().getAttrInfo();
            cost = BooleanUtils.isTrue(payType)
                    ? cost.add(attrInfo.getCost().add(attrInfo.getTaxAndSecondPrice()).subtract(attrInfo.getPaidPrice()))
                    : cost.add(attrInfo.getCost().add(attrInfo.getTaxAndSecondPrice()));
        }
        if (cost.compareTo(BigDecimal.ZERO) < 1) {
            throw new CrmebException("订单异常!");
        }
        ChannelMerchantAccount channelMerchantAccount = channelMerchantAccountService.getOne(Wrappers.<ChannelMerchantAccount>lambdaQuery().eq(ChannelMerchantAccount::getMerId, storeOrder.getMerId()));
        if (channelMerchantAccount == null) {
            throw new CrmebException("商户不存在!");
        }
        if (channelMerchantAccount.getAccount().compareTo(cost) < 0) {
            throw new CrmebException("商户余额不足!");
        }
        ChannelMerchantAccount merchantAccount = new ChannelMerchantAccount();
        merchantAccount.setMerId(storeOrder.getMerId());
        merchantAccount.setAccount(cost.negate());
        channelMerchantAccountService.calcMoney(merchantAccount);
        log.info("扣除可用余额成功,减少商户可用金额, 商户: {}, 金额: {}", storeOrder.getMerId(), cost);
        accountFlowService.saveAccountFlow(storeOrder.getMerId(), storeOrder.getId(), null, null,
                AccountFlowTypeEnum.PRODUCT, cost.negate(), null, null, BooleanUtils.isTrue(payType) ? "售价低于成本价" : "成本价");
        //修改订单状态
        storeOrder.setAbnormal(0);
        updateById(storeOrder);
        storeOrderInfoService.update(Wrappers.lambdaUpdate(StoreOrderInfo.class).set(StoreOrderInfo::getAbnormal, 0).eq(StoreOrderInfo::getOrderId, storeOrder.getId()));
        storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), "deduct_account", "商户扣除可用余额");
        return true;
    }

    /**
     * 获取商家小程序首页订单数量
     *
     * @param merId
     * @return
     */
    @Override
    public List<OrderNumberResponse> getOrderNumber(Integer merId) {
        int count = storeOrderInfoService.count(Wrappers.lambdaQuery(StoreOrderInfo.class)
                .inSql(StoreOrderInfo::getOrderId, "select id from eb_store_order where mer_id = " + merId)
//                .like(StoreOrderInfo::getInfo, "\"isEurope\":1,"));
                .eq(StoreOrderInfo::getIsEurope, 1));
        int all = storeOrderInfoService.count(Wrappers.lambdaQuery(StoreOrderInfo.class).inSql(StoreOrderInfo::getOrderId, "select id from eb_store_order where mer_id = " + merId));
        int afterSales = storeOrderInfoService.count(Wrappers.lambdaQuery(StoreOrderInfo.class).inSql(StoreOrderInfo::getOrderId, "select id from eb_store_order where mer_id = " + merId)
                .and(e -> e.eq(StoreOrderInfo::getStatus, -1).or().eq(StoreOrderInfo::getStatus, -2)));
        return Stream.of(new OrderNumberResponse().setType(1).setNumber(count), new OrderNumberResponse().setType(2).setNumber(all - count), new OrderNumberResponse().setType(3).setNumber(afterSales)).collect(Collectors.toList());
    }

    /**
     * 数据分析
     *
     * @param merId
     * @return
     */
    @Override
    public List<DataAnalysisResponse> dataAnalysis(Integer merId, PageParamRequest pageParamRequest) {
        Page<Object> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<StoreOrder> storeOrderList = dao.selectList(Wrappers.lambdaQuery(StoreOrder.class).eq(StoreOrder::getMerId, merId).ne(StoreOrder::getStatus, 5).ne(StoreOrder::getStatus, 0).orderByDesc(StoreOrder::getCreateTime));
        List<Integer> orderIdList = storeOrderList.stream().map(StoreOrder::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(storeOrderList)) {
            return null;
        }
        //订单收入
        List<MerFreezeBill> freezeBillList = merFreezeBillService.list(Wrappers.lambdaQuery(MerFreezeBill.class).in(MerFreezeBill::getOrderId, orderIdList));
        Map<Integer, MerFreezeBill> freezeBillMap = freezeBillList.stream().collect(Collectors.toMap(MerFreezeBill::getOrderId, e -> e));
        List<DataAnalysis> orderList = storeOrderList.stream().map(e -> new DataAnalysis().setCreateTime(e.getCreateTime()).setOrderNumber(e.getOrderId())
                .setOrderIncome(freezeBillMap.get(e.getId()) == null ? BigDecimal.ZERO : freezeBillMap.get(e.getId()).getAmountFrozen())
                .setOrderSales(e.getPayPrice().add(e.getDeductionPrice()))
                .setFormatDate(DateUtil.dateToStr(e.getCreateTime(), "yyyy-MM"))).collect(Collectors.toList());
        Map<String, List<DataAnalysis>> collect = orderList.stream().collect(Collectors.groupingBy(DataAnalysis::getFormatDate));
        List<DataAnalysisResponse> list = new ArrayList<>();
        for (Entry<String, List<DataAnalysis>> entry : collect.entrySet()) {
            DataAnalysisResponse dataAnalysisResponse = new DataAnalysisResponse();
            List<DataAnalysis> value = entry.getValue();
            dataAnalysisResponse.setYears(entry.getKey());
            CommonPage<DataAnalysis> dataAnalysisCommonPage = CommonPage.restPage(CommonPage.copyPageInfo(page, value.stream().sorted(Comparator.comparing(DataAnalysis::getCreateTime).reversed()).collect(Collectors.toList())));
            dataAnalysisResponse.setOrderList(dataAnalysisCommonPage);
            //通过日期查 订单数 销售额 收入
            QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("GROUP_CONCAT(id) order_id,sum(pay_price+deduction_price) as pay_price", "count(id) as id");
            queryWrapper.ne("status", 0).ne("status", 5).like("create_time", entry.getKey()).eq("mer_id", merId);
            StoreOrder storeOrder = dao.selectOne(queryWrapper);
            dataAnalysisResponse.setSales(storeOrder.getPayPrice() == null ? BigDecimal.ZERO : storeOrder.getPayPrice());
            dataAnalysisResponse.setOrderQuantity(storeOrder.getId());
            MerFreezeBill merFreezeBill = new MerFreezeBill();
            if (StringUtils.isNotBlank(storeOrder.getOrderId())) {
                List<String> stringList = Arrays.asList(storeOrder.getOrderId().split(","));
                QueryWrapper<MerFreezeBill> queryWrapperBill = new QueryWrapper<>();
                queryWrapperBill.select("ifnull(sum(amount_frozen),0) as amount_frozen").in("order_id", stringList);
                merFreezeBill = merFreezeBillService.getOne(queryWrapperBill);
            }
            dataAnalysisResponse.setIncome(merFreezeBill.getAmountFrozen() == null ? BigDecimal.ZERO : merFreezeBill.getAmountFrozen());
            list.add(dataAnalysisResponse);
        }
        list.sort(Comparator.comparing(DataAnalysisResponse::getYears).reversed());
        return list;
    }

    private List<MerStoreOrderExcelVo> formatStoreOrderExcelVo(List<StoreOrderInfo> childOrderList) {
        List<MerStoreOrderExcelVo> storeOrderExcelVoList = new ArrayList<>();
        if (CollectionUtils.isEmpty(childOrderList)) {
            return storeOrderExcelVoList;
        }
        //主订单集合
        List<Integer> orderIdList = childOrderList.stream().map(StoreOrderInfo::getOrderId).distinct().collect(Collectors.toList());
        List<StoreOrder> storeOrderList = dao.selectList(Wrappers.lambdaQuery(StoreOrder.class).in(StoreOrder::getId, orderIdList));
        Map<Integer, StoreOrder> storeOrderMap = storeOrderList.stream().collect(Collectors.toMap(StoreOrder::getId, e -> e));
        //下单用户列表
        Set<Integer> userIdList = storeOrderList.stream().map(StoreOrder::getUid).collect(Collectors.toSet());
        List<User> userList = userService.list(Wrappers.lambdaQuery(User.class).in(User::getUid, userIdList));
        //推广人列表
        Map<Integer, User> spreadMap = new HashMap<>();
        userList.forEach(e -> {
            if (spreadMap.get(e.getUid()) == null) {
                User spread = Optional.ofNullable(userService.getById(e.getSpreadUid())).orElse(new User());
                spreadMap.put(e.getUid(), spread);
            }
        });
        for (StoreOrderInfo storeOrderInfo : childOrderList) {
            MerStoreOrderExcelVo storeOrderExcelVo = new MerStoreOrderExcelVo();
            StoreOrder storeOrder = storeOrderMap.get(storeOrderInfo.getOrderId());
            storeOrderExcelVo.setCreateTime(DateFormatUtils.format(storeOrder.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
            storeOrderExcelVo.setOrderNumber(storeOrder.getOrderId());
            //主订单
            storeOrderExcelVo.setOrderType(storeOrder.getShippingType() == 1 ? "快递订单" : "自提订单");
            storeOrderExcelVo.setCreateName(storeOrder.getCreateName());
            storeOrderExcelVo.setSpreadName(spreadMap.get(storeOrder.getUid()) != null ? spreadMap.get(storeOrder.getUid()).getNickname() : "");
            storeOrderExcelVo.setPayTypeStr(getPayType(storeOrder.getPayType()));
            if (storeOrder.getUseIntegral() > 0) {
                storeOrderExcelVo.setPayTypeStr(storeOrderExcelVo.getPayTypeStr() + " / 积分抵扣");
            }
            storeOrderExcelVo.setTotalPriceCNY(storeOrder.getPayPrice().add(storeOrder.getDeductionPrice()).add(storeOrder.getCouponPrice()).add(storeOrder.getVipReducePrice()));
            storeOrderExcelVo.setGoodsPriceCNY(storeOrder.getTotalPrice());
            storeOrderExcelVo.setFreightAndTaxPrice(storeOrder.getPayPostage());
            storeOrderExcelVo.setPayPrice(storeOrder.getPayPrice());
            storeOrderExcelVo.setDeductedPrice(storeOrder.getDeductionPrice());
            storeOrderExcelVo.setCouponPrice(storeOrder.getCouponPrice());
            storeOrderExcelVo.setChildOrderNumber(storeOrderInfo.getChildOrderNumber());
            storeOrderExcelVo.setOrderStatus(getStatusStr(storeOrderInfo.getStatus()));
            storeOrderExcelVo.setRefundStatus(getRefundStatusStr(storeOrderInfo.getRefundStatus()));
            //退款信息
            if (storeOrderInfo.getRefundStatus() == 2 || storeOrderInfo.getRefundStatus() == 3) {
                List<StoreAccountInfo> accountInfoList = storeAccountInfoService.list(Wrappers.lambdaQuery(StoreAccountInfo.class).eq(StoreAccountInfo::getUid, storeOrder.getUid())
                        .eq(StoreAccountInfo::getOrderId, storeOrderInfo.getChildOrderNumber()).eq(StoreAccountInfo::getTradeType, OrderTradeTypeEnum.REFUND.getType()).orderByAsc(StoreAccountInfo::getCreateTime));
                storeOrderExcelVo.setRefundPrice(accountInfoList.stream().map(StoreAccountInfo::getTradePrice).map(BigDecimal::toString).collect(Collectors.joining(" / ")));
                storeOrderExcelVo.setRefundTime(accountInfoList.stream().map(StoreAccountInfo::getCreateTime).map(e -> DateFormatUtils.format(e, "yyyy-MM-dd HH:mm:ss")).collect(Collectors.joining(" / ")));
                Set<Integer> adminIdList = accountInfoList.stream().map(StoreAccountInfo::getOperateId).collect(Collectors.toSet());
                if (CollectionUtils.isNotEmpty(adminIdList)) {
                    List<SystemAdmin> systemAdminList = systemAdminService.list(Wrappers.lambdaQuery(SystemAdmin.class).in(SystemAdmin::getId, adminIdList));
                    Map<Integer, String> systemAdminMap = systemAdminList.stream().collect(Collectors.toMap(SystemAdmin::getId, SystemAdmin::getRealName));
                    storeOrderExcelVo.setRefundOperator(accountInfoList.stream().map(StoreAccountInfo::getOperateId).map(systemAdminMap::get).collect(Collectors.joining(" / ")));
                }
            }
            StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
            StoreProductCartProductInfoResponse productInfo = storeCartResponse.getProductInfo();
            StoreProductAttrValue attrInfo = productInfo.getAttrInfo();
            //商品信息
            storeOrderExcelVo.setProductId(storeCartResponse.getProductId());
            storeOrderExcelVo.setProductName(productInfo.getStoreName());
            storeOrderExcelVo.setBrandName(productInfo.getBrandName());
            // 图片压缩
            String imgUrl = attrInfo.getImage();
            imgUrl = StringUtil.isEmpty(imgUrl) ? "" : imgUrl.substring(0, !imgUrl.contains("?") ? imgUrl.length() : imgUrl.indexOf("?")) + "?x-oss-process=image/resize,m_fill,w_100,h_100";
            storeOrderExcelVo.setImage(imgUrl);
            storeOrderExcelVo.setKeyword(productInfo.getKeyword());
            storeOrderExcelVo.setSpecification(attrInfo.getAttrValue());
            storeOrderExcelVo.setQuantity(storeCartResponse.getCartNum());
            //子订单价格信息
            storeOrderExcelVo.setOtPriceEUR(attrInfo.getOtPrice() == null ? productInfo.getOtPrice() : attrInfo.getOtPrice());
            storeOrderExcelVo.setCostCNY(attrInfo.getCost());
            //价格转换处理
            storeOrderExcelVo.setOtPriceCNY(priceUtil.eur2RmbStatic(storeOrderExcelVo.getOtPriceEUR(), storeOrderInfo.getExchangeRate()));
            storeOrderExcelVo.setCostEUR(attrInfo.getCost() == null ? null : priceUtil.rmb2EurStatic(attrInfo.getCost(), storeOrderInfo.getExchangeRate()));

            storeOrderExcelVo.setPrice(attrInfo.getPrice());
            storeOrderExcelVo.setSecondPrice(attrInfo.getSecondPrice());
            storeOrderExcelVo.setTaxPrice(attrInfo.getTaxPrice());
            storeOrderExcelVo.setProductPaidPrice(attrInfo.getProductPaidPrice());
            storeOrderExcelVo.setSubDeductionPrice(storeOrderInfo.getDeductionPrice());
            storeOrderExcelVo.setSubCouponPrice(storeOrderInfo.getCouponPrice());
            storeOrderExcelVo.setPaidPrice(storeOrderInfo.getPayPrice());
            storeOrderExcelVo.setMemberDiscountPrice(storeOrderInfo.getVipReducePrice());
            //发货信息
            storeOrderExcelVo.setTempName(StockAreaTempEnum.getByTempId(productInfo.getTempId()).getStockAreaName());
            if (OrderStatusEnum.SHIPPED.getCode().equals(storeOrderInfo.getStatus()) || OrderStatusEnum.COMPLETE.getCode().equals(storeOrderInfo.getStatus())) {
                List<OrderInfoDelivery> orderInfoDeliveryList = orderInfoDeliveryService.list(Wrappers.lambdaQuery(OrderInfoDelivery.class).eq(OrderInfoDelivery::getOrderInfoId, storeOrderInfo.getId()).orderByAsc(OrderInfoDelivery::getId));
                storeOrderExcelVo.setDeliveryTime(orderInfoDeliveryList.stream().map(OrderInfoDelivery::getCreateTime).map(e -> DateFormatUtils.format(e, "yyyy-MM-dd HH:mm:ss")).collect(Collectors.joining(" / ")));
                storeOrderExcelVo.setDeliveryCompany(orderInfoDeliveryList.stream().map(OrderInfoDelivery::getDeliveryCompany).collect(Collectors.joining(" / ")));
                storeOrderExcelVo.setDeliveryNumber(orderInfoDeliveryList.stream().map(OrderInfoDelivery::getDeliveryNumber).collect(Collectors.joining(" / ")));
            }
            //收货人信息
            storeOrderExcelVo.setRealName(storeOrder.getRealName());
            storeOrderExcelVo.setUserPhone(storeOrder.getUserPhone());
            storeOrderExcelVo.setDetail(storeOrder.getUserAddress());
            storeOrderExcelVo.setIdCard(storeOrder.getIdCard());
            //商品汇率
            storeOrderExcelVo.setExchangeRate(storeOrderInfo.getExchangeRate());
            //加价计算方式
            String calculation = priceUtil.getCalculation(productInfo.getMarkupType(), productInfo.getPriceChange(), null);
            int count = storeOrderStatusService.count(Wrappers.lambdaQuery(StoreOrderStatus.class).eq(StoreOrderStatus::getChangeType, Constants.ORDER_UPDATE_PRICE).eq(StoreOrderStatus::getOid, storeOrderInfo.getOrderId())
                    .eq(StoreOrderStatus::getOrderNumber, storeOrderInfo.getChildOrderNumber()));
            if (count > 0) {
                calculation = "订单提交后修改价格";
            }
            storeOrderExcelVo.setCalculation(calculation);
            storeOrderExcelVo.setNote(storeOrderStatusService.getNote(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_MERCHANT_NOTE));
            storeOrderExcelVo.setRefundReason(storeOrderInfo.getRefundReasonWapExplain());
            storeOrderExcelVoList.add(storeOrderExcelVo);
        }
        return storeOrderExcelVoList;
    }


    /**
     * 送货上门
     *
     * @param request    StoreOrderSendRequest 发货参数
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    private void delivery(StoreOrderSendRequest request, StoreOrder storeOrder) {
        ValidateFormUtil.isPhone(request.getExpressCode(), "收货人联系方式");

        try {
            //送货信息
            storeOrder.setDeliveryName(request.getExpressId());
            storeOrder.setDeliveryId(request.getExpressCode());
            storeOrder.setStatus(Constants.ORDER_STATUS_H5_SPIKE);
            storeOrder.setDeliveryType("send");
            updateById(storeOrder);

            //获取购买商品名称
            List<Integer> orderIdList = new ArrayList<>();
            orderIdList.add(storeOrder.getId());

            HashMap<Integer, List<StoreOrderInfoVo>> orderInfoMap = StoreOrderInfoService.getMapInId(orderIdList);
            if (orderInfoMap.isEmpty() || !orderInfoMap.containsKey(storeOrder.getId())) {
                throw new CrmebException("没有找到购买的商品信息");
            }
            List<String> productNameList = new ArrayList<>();
            for (StoreOrderInfoVo storeOrderInfoVo : orderInfoMap.get(storeOrder.getId())) {
//                productNameList.add(storeOrderInfoVo.getInfo().getJSONObject("productInfo").getString("store_name"));
                productNameList.add(storeOrderInfoVo.getInfo().getProductInfo().getStoreName());
            }


            //订单记录增加
            String message = Constants.ORDER_LOG_MESSAGE_DELIVERY.replace("{deliveryName}", request.getExpressId()).replace("{deliveryCode}", request.getExpressCode());
            storeOrderStatusService.createLog(request.getId(), Constants.ORDER_LOG_DELIVERY, message);

            //微信模板消息发送
            HashMap<String, String> map = new HashMap<>();
            map.put(Constants.WE_CHAT_TEMP_KEY_FIRST, "订单发货提醒");
            map.put("keyword1", StringUtils.join(productNameList, "|"));
            map.put("keyword2", DateUtil.dateToStr(storeOrder.getCreateTime(), Constants.DATE_FORMAT));
            map.put("keyword3", storeOrder.getUserAddress());
            map.put("keyword4", request.getExpressId());
            map.put("keyword5", request.getExpressCode());
            map.put(Constants.WE_CHAT_TEMP_KEY_END, "欢迎再次购买！");

            templateMessageService.push(Constants.WE_CHAT_TEMP_KEY_DELIVERY, map, storeOrder.getUid(), Constants.PAY_TYPE_WE_CHAT_FROM_PUBLIC);

        } catch (Exception e) {
            throw new CrmebException("送货上门发货失败！");
        }
    }

    /**
     * 虚拟
     *
     * @param request    StoreOrderSendRequest 发货参数
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-10
     */
    private void virtual(StoreOrderSendRequest request, StoreOrder storeOrder) {
        try {
            //快递信息
            storeOrder.setDeliveryType("fictitious");
            storeOrder.setStatus(Constants.ORDER_STATUS_H5_SPIKE);
            updateById(storeOrder);

            //订单记录增加
            storeOrderStatusService.createLog(request.getId(), Constants.ORDER_LOG_DELIVERY_VI, Constants.ORDER_LOG_DELIVERY_VI);

            //微信模板消息发送
        } catch (Exception e) {
            e.printStackTrace();
            throw new CrmebException("虚拟物品发货失败");
        }


    }

    /**
     * 获取总数
     *
     * @param request 请求参数
     * @return Integer
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private List<StoreOrderInfo> getCount(StoreOrderSearchRequest request) {
        StoreOrderSearchRequest searchRequest = new StoreOrderSearchRequest();
        BeanUtils.copyProperties(request, searchRequest);
        searchRequest.setStatus(null);
        getStoreOrderListRequest(searchRequest);
        return dao.selectChildCountByCondition(searchRequest);
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private void getRequestWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        getRequestOrderIdWhere(queryWrapper, request);
        getRequestUidWhere(queryWrapper, request);
        getRequestTimeWhere(queryWrapper, request);
        if (request.getSource() != null) {
            queryWrapper.eq("source", request.getSource());
        }
        if (StringUtils.isNotBlank(request.getPayType())) {
            queryWrapper.eq("pay_type", request.getPayType());
        }
        if (StringUtils.isNotBlank(request.getUserPhone())) {
            queryWrapper.like("user_phone", request.getUserPhone());
        }
        if (request.getShippingType() != null) {
            queryWrapper.eq("shipping_type", request.getShippingType());
        }
    }

    private void getIsDelWhere(QueryWrapper<StoreOrder> queryWrapper, Boolean isDel) {
        if (null != isDel) {
            queryWrapper.eq("is_del", isDel);
        }
    }

    /**
     * 查询条件 - 后台删除标识
     *
     * @param queryWrapper
     * @param isSystemDel
     */
    private void getIsSystemDelWhere(QueryWrapper<StoreOrder> queryWrapper, Boolean isSystemDel) {
        if (null != isSystemDel) {
            queryWrapper.eq("is_system_del", isSystemDel);
        }
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private void getRequestOrderIdWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        if (StringUtils.isNotBlank(request.getOrderId())) {
            queryWrapper.eq("order_id", request.getOrderId());
        }
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private void getRequestUidWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        if (null != request.getUid() && request.getUid() > 0) {
            queryWrapper.eq("uid", request.getUid());
        }
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private void getRequestTimeWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        if (StringUtils.isNotBlank(request.getDateLimit())) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
    }

    //

    /**
     * h5 订单查询 where status 封装
     * 退款状态（0 未退款 1 申请中 2 已退款）
     * 订单状态（-1 : 申请退款 -2 : 退货成功 0：未支付，待发货；1：待收货；2：已收货，待评价；3：已完成；4：已取消；）
     *
     * @param queryWrapper 查询条件
     * @param status       状态
     */
    public void statusApiByWhere(LambdaQueryWrapper<StoreOrder> queryWrapper, int status) {
        switch (status) {
            case Constants.ORDER_STATUS_H5_UNPAID: // 未支付
                queryWrapper.eq(StoreOrder::getPaid, false);
                queryWrapper.eq(StoreOrder::getStatus, 0);
                queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_NOT_SHIPPED: // 待发货
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getStatus, 1);
                //queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_SPIKE: // 待收货
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getStatus, 2);
                //queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_BARGAIN: //  待评价
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getStatus, 3);
                //queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_COMPLETE: // 已完成
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getStatus, 4);
                //queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_CANCEL: // 已取消
                queryWrapper.eq(StoreOrder::getPaid, false);
                queryWrapper.eq(StoreOrder::getStatus, 5);
                //queryWrapper.eq(StoreOrder::getRefundStatus, 0);
                break;
            case Constants.ORDER_STATUS_H5_REFUNDING: // 退款中
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getRefundStatus, 1);
                break;
            case Constants.ORDER_STATUS_H5_REFUNDED: // 已退款
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getRefundStatus, 2);//退货退款
                break;
            case Constants.ORDER_STATUS_H5_REFUND: // 退款
                queryWrapper.eq(StoreOrder::getPaid, true);
                queryWrapper.eq(StoreOrder::getRefundStatus, 3); //补偿性退款
                break;
        }
        queryWrapper.eq(StoreOrder::getIsDel, false);
        queryWrapper.eq(StoreOrder::getIsSystemDel, false);
    }

    /**
     * 根据订单状态获取where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param status       String 类型
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private void getStatusWhere(QueryWrapper<StoreOrder> queryWrapper, String status) {
        if (null == status) {
            return;
        }
        status = "all".equals(status) ? Constants.ORDER_STATUS_PAID : status;
        Integer orderStatus = null; //订单状态
        Integer paidStatus = null; //支付状态
        Integer refundStatus = null; //退款状态
        Integer deleteStatus = null; //删除状态
        Integer systemDeleteStatus = null; //系统删除
        Integer shippingType = null; //配送方式
        switch (status) {
            case Constants.ORDER_STATUS_UNPAID: //未支付
                paidStatus = 0; //支付状态
                orderStatus = 0; //订单状态
                refundStatus = 0; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                paidStatus = 1; //支付状态
                orderStatus = 1; //订单状态
                //refundStatus = 0; //退款状态
                shippingType = 1; //配送方式
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_SPIKE: //待收货
                paidStatus = 1; //支付状态
                orderStatus = 2; //订单状态
                //refundStatus = 0; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_BARGAIN: //待评价
                paidStatus = 1; //支付状态
                orderStatus = 3; //订单状态
                refundStatus = 0; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_COMPLETE: //交易完成
                paidStatus = 1; //支付状态
                orderStatus = 4; //订单状态
                refundStatus = 0; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_TOBE_WRITTEN_OFF: //待核销
                paidStatus = 1; //支付状态
                orderStatus = 0; //订单状态
                refundStatus = 0; //退款状态
                shippingType = 2; //配送方式
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_REFUNDING: //退款中
                paidStatus = 1; //支付状态
                refundStatus = 1; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_REFUNDED: //退货退款
                paidStatus = 1; //支付状态
                refundStatus = 2; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_REFUNDED_PART: //补偿性退款
                paidStatus = 1; //支付状态
                refundStatus = 3; //退款状态
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                break;
            case Constants.ORDER_STATUS_DELETED: //已删除
                deleteStatus = 1; //删除状态
                systemDeleteStatus = 1; //系统删除,  未付款超时自动删除
                break;
            case Constants.ORDER_STATUS_PAID:  //已支付
                deleteStatus = 0; //删除状态
                systemDeleteStatus = 0; //系统删除
                queryWrapper.in("status", 1, 2, 3, 4);
            default:
                break;
        }
        if (paidStatus != null) {
            queryWrapper.eq("paid", paidStatus);
        }

        if (orderStatus != null) {
            queryWrapper.eq("status", orderStatus);
        }

        if (refundStatus != null) {
            queryWrapper.eq("refund_status", refundStatus);
        }

        if (shippingType != null) {
            queryWrapper.eq("shipping_type", shippingType);
        }

        if (deleteStatus != null) {
            if (deleteStatus == 1 && systemDeleteStatus == 1) {
                queryWrapper.and(i -> i.or().eq("is_del", 1).or().eq("is_system_del", 1));
            } else {
                queryWrapper.eq("is_del", deleteStatus);
            }
        }
    }


    /**
     * 获取订单状态
     *
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    @Override
    public Map<String, String> getStatus(StoreOrder storeOrder) {
        Map<String, String> map = new HashMap<>();
        map.put("key", "");
        map.put("value", "");
        if (null == storeOrder) {
            return map;
        }
        //未支付
        if (!storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_UNPAID);
            map.put("value", Constants.ORDER_STATUS_STR_UNPAID);
            return map;
        }
        //未发货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && storeOrder.getRefundStatus() == 0
                && storeOrder.getShippingType() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_NOT_SHIPPED);
            map.put("value", Constants.ORDER_STATUS_STR_NOT_SHIPPED);
            return map;
        }
        //待收货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 1
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_SPIKE);
            map.put("value", Constants.ORDER_STATUS_STR_SPIKE);
            return map;
        }
        //待评价
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 1
                && storeOrder.getRefundStatus() == 2
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_BARGAIN);
            map.put("value", Constants.ORDER_STATUS_STR_BARGAIN);
            return map;
        }
        //完成
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 3
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_COMPLETE);
            map.put("value", Constants.ORDER_STATUS_STR_COMPLETE);
            return map;
        }
        //订单已取消
        if (!storeOrder.getPaid()
                && storeOrder.getStatus() == 4
                && storeOrder.getRefundStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_CANCEL);
            map.put("value", Constants.ORDER_STATUS_STR_CANCEL);
            return map;
        }
        //待核销
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && storeOrder.getRefundStatus() == 0
                && storeOrder.getShippingType() == 2
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_TOBE_WRITTEN_OFF);
            map.put("value", Constants.ORDER_STATUS_STR_TOBE_WRITTEN_OFF);
            return map;
        }

        //此处前端需要判断
        //退款中
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDING);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDING);
            return map;
        }
        //已退款
        if (storeOrder.getPaid()
                && storeOrder.getRefundStatus() == 2
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDED);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDED);
        }
        //未发货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 0
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_NOT_SHIPPED);
            map.put("value", Constants.ORDER_STATUS_STR_NOT_SHIPPED);
        }
        //待收货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 1
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_SPIKE);
            map.put("value", Constants.ORDER_STATUS_STR_SPIKE);
        }
        //用户已收货
        if (storeOrder.getPaid()
                && storeOrder.getStatus() == 2
                && !storeOrder.getIsDel()
                && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_COMPLETE);
            map.put("value", Constants.ORDER_STATUS_STR_TAKE);
        }


        //已删除
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_DELETED);
            map.put("value", Constants.ORDER_STATUS_STR_DELETED);
        }

        return map;
    }

    /**
     * 获取支付文字
     *
     * @param payType String 支付方式
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private String getPayType(String payType) {
        switch (payType) {
            case Constants.PAY_TYPE_NOT_PAY:
                return Constants.PAY_TYPE_STR_NOT_PAY;
            case Constants.PAY_TYPE_WE_CHAT:
                return Constants.PAY_TYPE_STR_WE_CHAT;
            case Constants.PAY_TYPE_WE_CHAT_NATIVE:
                return Constants.PAY_TYPE_STR_WE_CHAT_NATIVE;
            case Constants.PAY_TYPE_YUE:
                return Constants.PAY_TYPE_STR_YUE;
            case Constants.PAY_TYPE_OFFLINE:
                return Constants.PAY_TYPE_STR_OFFLINE;
            case Constants.PAY_TYPE_ALI_PAY:
                return Constants.PAY_TYPE_STR_ALI_PAY;
            case Constants.PAY_TYPE_TMALL_PAY:
                return Constants.PAY_TYPE_STR_TMALL_PAY;
            case Constants.PAY_TYPE_HK_PAY:
                return Constants.PAY_TYPE_STR_HK_PAY;
            case Constants.PAY_TYPE_ORAGE_PAY:
                return Constants.PAY_TYPE_STR_ORAGE_PAY;
            case Constants.PAY_TYPE_ADAPAY_DEGREE:
                return Constants.PAY_TYPE_STR_ADAPAY_DEGREE;
            case Constants.PAY_TYPE_ADAPAY_CN:
                return Constants.PAY_TYPE_STR_ADAPAY_CN;
            default:
                return Constants.PAY_TYPE_STR_OTHER;
        }
    }


    private String getRefundStatusStr(Integer refundStatus) {
        if (null == refundStatus) {
            return "";
        }
        if (Integer.valueOf(0).equals(refundStatus)) {
            return "未退款";
        } else if (Integer.valueOf(1).equals(refundStatus)) {
            return "申请中";
        } else if (Integer.valueOf(2).equals(refundStatus)) {
            return "已退款";
        } else if (Integer.valueOf(3).equals(refundStatus)) {
            return "补偿性退款";
        }
        return "";
    }

//    private String getSourceName(String source){
//        if (null == source){
//            return "";
//        }
//        if ("1".equals(source)){
//            return "寻物";
//        }else if ("2".equals(source)){
//            return "天猫";
//        }
//        return "";
//    }


    private String getStatusStr(Integer status) {
        if (status == null) {
            return "";
        }
        OrderStatusEnum[] orderStatusEnums = OrderStatusEnum.values();
        for (OrderStatusEnum orderStatusEnum : orderStatusEnums) {
            if (orderStatusEnum.getCode().equals(status)) {
                return orderStatusEnum.getMsg();
            }
        }
        return "";
    }

    /**
     * @param id
     * @return boolean
     * @throws
     * @description 商户确认完成订单
     * @author lvmd
     * @date 2022/1/5 9:40
     */
    @Override
    public boolean confirmReceiptOrder(Integer id, String remark) {
        // 快递订单：自建商品   1）快递订单；自建商品——待收货状态
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (Objects.isNull(storeOrderInfo)) {
            throw new CrmebException("该子订单不存在");
        }
        if (1 == storeOrderInfo.getAbnormal()) {
            throw new CrmebException("该订单为异常订单");
        }
        if (!storeOrderInfo.getStatus().equals(OrderStatusEnum.SHIPPED.getCode())) {
            throw new CrmebException("该子订单状态不是待收货状态");
        }
        if (!Objects.equals(storeOrderInfo.getAutonomous(), 1) && storeOrderInfo.getIsEurope() != 1) {
            throw new CrmebException("云仓商品平台发货订单仅支持补偿性退款!");
        }
        // 快递订单
        StoreOrder storeOrder = getById(storeOrderInfo.getOrderId());
        if (Objects.isNull(storeOrder)) {
            throw new CrmebException("主订单不存在");
        }
        if (1 != storeOrder.getShippingType()) {
            throw new CrmebException("商户只能完成快递订单");
        }
        //修改订单状态
        storeOrderInfo.setStatus(Constants.ORDER_STATUS_H5_COMPLETE);
        boolean update = storeOrderInfoService.updateById(storeOrderInfo);
        if (update) {
            //加入分销
            userService.joinDistribution(storeOrder, storeOrderInfo);
            //佣金解冻
            userCommissionService.completeCommission(storeOrderInfo);

            // 连连支付：担保确认
            Map<String, Object> confirmResult = orderUtils.securedConfirm(storeOrder);
            if(CollectionUtils.isEmpty(confirmResult) || null == confirmResult.get("result") || !"SUCCESS".equals(confirmResult.get("result"))){
                String msg = (CollectionUtils.isEmpty(confirmResult) || null == confirmResult.get("result")) ? "空" : confirmResult.get("result").toString();
                log.info("连连支付：担保确认失败，失败原因：{}", msg);
                throw new CrmebException("连连支付：担保确认失败，失败原因：" + msg);
            }
            log.info("---------------订单:{} 商户确认完成订单--------------------", storeOrderInfo.getChildOrderNumber());
            String message = StringUtils.isNotBlank(remark) ? "商户确认完成订单,备注：" + remark : "商户确认完成订单";
            storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), "confirm_receipt_mer", message);
            //修改总订单状态
            orderUtils.updateOrderStatus(storeOrderInfo.getOrderId());
        }
        return update;
    }

    /**
     * @param id orderInfoId
     * @return boolean
     * @throws
     * @description
     * @author lvmd
     * @date 2022/1/6 15:32
     */
    @Override
    public Boolean useSystemDelivery(Integer id) {
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (Objects.isNull(storeOrderInfo)) {
            throw new CrmebException("该子订单不存在");
        }
        if (LogisticsTypeEnum.DEFAULT.getCode().equals(storeOrderInfo.getLogisticsType())) {
            StoreOrderInfo updateOrderInfo = new StoreOrderInfo();
            updateOrderInfo.setId(id);
            updateOrderInfo.setLogisticsType(LogisticsTypeEnum.PLATFORM.getCode());
            return storeOrderInfoService.updateById(updateOrderInfo);
        }
        throw new CrmebException("该订单已选择平台物流方式");
    }

    @Override
    public boolean note(Integer id, String note) {
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
        if (storeOrderInfo == null) {
            throw new CrmebException("该订单不存在");
        }
        int count = storeOrderStatusService.count(Wrappers.<StoreOrderStatus>lambdaQuery().eq(StoreOrderStatus::getChangeType, Constants.ORDER_MERCHANT_NOTE)
                .eq(StoreOrderStatus::getOid, storeOrderInfo.getOrderId()).eq(StoreOrderStatus::getOrderNumber, storeOrderInfo.getChildOrderNumber()));
        note = (count > 0 ? "修改备注:" : "订单备注:") + note;
        //订单备注
        storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_MERCHANT_NOTE, note);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean independentDelivery(Integer id, boolean type, Integer merId, String ip) {
        String lockKey = "independent_delivery_order:" + id;
        RLock rLock = redisson.getLock(lockKey);
        try {
            if (!rLock.tryLock()) {
                throw new CrmebException("该订单正在处理!");
            }
            ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
            if (!Objects.equals(channelMerchant.getAutoPush(), 0)) {
                throw new CrmebException("该商户默认自动推送云仓商品");
            }
            StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);
            if (Objects.isNull(storeOrderInfo)) {
                throw new CrmebException("该订单不存在");
            }
            if (storeOrderInfo.getAbnormal() == 1) {
                throw new CrmebException("该订单为异常订单");
            }
            if (!Objects.equals(storeOrderInfo.getStatus(), 6)) {
                throw new CrmebException("该订单不是待确认状态");
            }
            if (Objects.equals(storeOrderInfo.getIsEurope(), 1)) {
                throw new CrmebException("该订单商品是自建商品");
            }
            if (storeOrderInfo.getAutonomous() != null) {
                throw new CrmebException("该订单已" + (storeOrderInfo.getAutonomous() == 0 ? "平台发货" : "自主发货"));
            }
            StoreOrder storeOrder = storeOrderService.getById(storeOrderInfo.getOrderId());
            if (!Objects.equals(storeOrder.getMerId(), merId)) {
                throw new CrmebException("订单异常");
            }
            //订单商品转自建
            storeOrderInfo.setAutonomous(type ? 1 : 0);
            if (type) {
                storeOrderInfo.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                if (storeOrder.getStatus().equals(OrderStatusEnum.CONFIRM.getCode())) {
                    storeOrder.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                    updateById(storeOrder);
                }
                //财务退回
                StoreCartResponse storeCartResponse = JSON.parseObject(storeOrderInfo.getInfo(), StoreCartResponse.class);
                StoreProductAttrValue attrInfo = storeCartResponse.getProductInfo().getAttrInfo();
                int adminId = 0;
                if (Objects.isNull(storeOrder.getActivityGroupId())){
                    adminId = systemAdminService.getAdminId();
                }
                Boolean payType = orderUtils.getPayType(storeOrder.getPayType());
                ChannelMerchantAccount merchantAccount = new ChannelMerchantAccount().setMerId(merId);
                //增加商户可用余额
                BigDecimal increaseAccount = BigDecimal.ZERO;
                if (payType == null) {
                    increaseAccount = attrInfo.getCost().add(attrInfo.getTaxAndSecondPrice());
                } else if (payType) {
                    BigDecimal profit = attrInfo.getPaidPrice().subtract(attrInfo.getCost()).subtract(attrInfo.getTaxAndSecondPrice());
                    if (profit.compareTo(BigDecimal.ZERO) < 0) {
                        increaseAccount = profit.negate();
                    }
                } else {
                    increaseAccount = attrInfo.getCost().add(attrInfo.getTaxAndSecondPrice());
                }
                merchantAccount.setAccount(increaseAccount);
                channelMerchantAccountService.calcMoney(merchantAccount);
                log.info("商户自主发货,增加商户可用余额，商户:{},订单编号:{},金额:{}", merId, storeOrderInfo.getChildOrderNumber(), increaseAccount);
                accountFlowService.saveAccountFlow(storeOrder.getMerId(), storeOrder.getId(), adminId, ip,
                        AccountFlowTypeEnum.PRODUCT, increaseAccount, null, null, "自主发货");
                //云仓商品库存增加
                storeProductAttrValueService.addProductValueStock(storeOrderInfo);
            }
            storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), "independent_delivery", "商户选择" + (type ? "自主发货" : "平台发货"));
            return storeOrderInfoService.updateById(storeOrderInfo);
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    @Override
    public boolean offlineConfirm(Integer id, boolean type, String receiptVoucher, Integer merId, String clientIp) {
        StoreOrder storeOrder = storeOrderService.getById(id);
        if (storeOrder == null) {
            throw new CrmebException("该订单不存在");
        }
        if (!Objects.equals(storeOrder.getPayType(), Constants.PAY_TYPE_OFFLINE)) {
            throw new CrmebException("该订单不是线下支付订单");
        }
        if (storeOrder.getPaid() && storeOrder.getStatus() != 0) {
            throw new CrmebException("该订单不是待支付状态");
        }
        if (type) {
            storeOrder.setReceiptVoucher(receiptVoucher);
            orderPayService.afterPaySuccess(storeOrder);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePickingProduct(UpdatePickingProductRequest request) {
        StoreOrder storeOrder = storeOrderService.getById(request.getOrderId());
        if (storeOrder == null) {
            throw new CrmebException("该订单不存在");
        }
        StoreOrderInfoPicking orderInfoPicking = storeOrderInfoPickingService.getById(request.getOrderInfoId());
        if (orderInfoPicking == null || orderInfoPicking.getIsDel() == 1) {
            throw new CrmebException("该商品不存在");
        }
        if (request.getNum() != null && !Objects.equals(orderInfoPicking.getNum(), request.getNum())) {
            if (request.getNum() == 0) {
                storeOrderInfoPickingService.update(Wrappers.<StoreOrderInfoPicking>lambdaUpdate()
                        .set(StoreOrderInfoPicking::getIsDel, 1).eq(StoreOrderInfoPicking::getId, request.getOrderInfoId()));
            } else if (request.getNum() > 0) {
                //库存校验
                //StoreProductAttrValue attrValue = storeProductAttrValueService.getById(orderInfoPicking.getUnique());
                StoreProductAttrValue attrValue = storeProductAttrValueService.getOne(Wrappers.lambdaQuery(StoreProductAttrValue.class)
                        .eq(StoreProductAttrValue::getSourceSkuId, orderInfoPicking.getUnique())
                        .eq(StoreProductAttrValue::getProductId, orderInfoPicking.getProductId())
                        .last("LIMIT 1"));
                if (attrValue == null || attrValue.getStock() < request.getNum()) {
                    throw new CrmebException("库存不足");
                }
                storeOrderInfoPickingService.update(Wrappers.<StoreOrderInfoPicking>lambdaUpdate()
                        .set(StoreOrderInfoPicking::getNum, request.getNum()).eq(StoreOrderInfoPicking::getId, request.getOrderInfoId()));
            } else {
                throw new CrmebException("数量异常");
            }
        }
        if (request.getPrice() != null && request.getPrice().compareTo(orderInfoPicking.getPayPrice()) != 0) {
            StoreCartResponse storeCartResponse = JSON.parseObject(orderInfoPicking.getInfo(), StoreCartResponse.class);
            StoreProductAttrValue attrInfo = storeCartResponse.getProductInfo().getAttrInfo();
            BigDecimal minPrice = attrInfo.getCost().add(orderInfoPicking.getSecondPrice());
            if (minPrice.compareTo(request.getPrice()) > 0) {
                throw new CrmebException("该商品最低价格" + minPrice);
            }
            attrInfo.setPrice(request.getPrice());
            attrInfo.setPaidPrice(request.getPrice());
            attrInfo.setProductPaidPrice(request.getPrice().subtract(attrInfo.getTaxAndSecondPrice()));
            attrInfo.setSubTotalPrice(attrInfo.getPaidPrice());
            String info = JSON.toJSONString(storeCartResponse);
            storeOrderInfoPickingService.update(Wrappers.<StoreOrderInfoPicking>lambdaUpdate()
                    .set(StoreOrderInfoPicking::getPayPrice, request.getPrice()).set(StoreOrderInfoPicking::getInfo, info)
                    .eq(StoreOrderInfoPicking::getId, request.getOrderInfoId()));
        }
        //处理主订单金额
        List<StoreOrderInfoPicking> infoPickingList = storeOrderInfoPickingService.list(Wrappers.<StoreOrderInfoPicking>lambdaQuery()
                .eq(StoreOrderInfoPicking::getOrderId, request.getOrderId()).eq(StoreOrderInfoPicking::getIsDel, 0));
        BigDecimal payPrice = BigDecimal.ZERO;
        BigDecimal payPostage = BigDecimal.ZERO;
        Integer num = 0;
        for (StoreOrderInfoPicking info : infoPickingList) {
            payPrice = payPrice.add(info.getPayPrice().multiply(BigDecimal.valueOf(info.getNum())));
            payPostage = payPostage.add(info.getSecondPrice().multiply(BigDecimal.valueOf(info.getNum())));
            num += info.getNum();
        }
        storeOrder.setPayPrice(payPrice);
        storeOrder.setPayPostage(payPostage);
        storeOrder.setTotalPrice(payPrice.subtract(payPostage));
        storeOrder.setTotalNum(num);
        storeOrderService.updateById(storeOrder);
        return true;
    }

    @Override
    public boolean refundGoods(RefundGoodsRequest request) {
        //退货逻辑
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(request.getInfoId());
        if (null == storeOrderInfo) {
            throw new CrmebException("没有找到订单信息");
        }
        if (storeOrderInfo.getRefundStatus() != 1 && storeOrderInfo.getStatus() != -1) {
            throw new CrmebException("该订单不是申请退款状态");
        }
        StoreOrderRefundApply refundApply = storeOrderRefundApplyService.getOne(Wrappers.<StoreOrderRefundApply>lambdaQuery()
                .eq(StoreOrderRefundApply::getInfoId, request.getInfoId())
                .orderByDesc(StoreOrderRefundApply::getId).last("LIMIT 1"));
        if (null == refundApply) {
            throw new CrmebException("订单申请退款记录不存在");
        }
        if (refundApply.getProcessType() != null) {
            throw new CrmebException("该订单已处理");
        }
        refundApply.setProcessType(1);
        refundApply.setProcessTime(new Date());
        refundApply.setReturnConsignee(request.getReturnConsignee());
        refundApply.setReturnPhone(request.getReturnPhone());
        refundApply.setReturnAddress(request.getReturnAddress());
        storeOrderRefundApplyService.updateById(refundApply);
        //退货状态
        storeOrderInfo.setRefundStatus(4);
        storeOrderInfoService.updateById(storeOrderInfo);
        storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_LOG_REFUND_GOODS, "同意退货");
        return true;
    }

    /**
     * 功能描述: 海带云发货
     * @Param: [orderSn, dlyCodes, shipNos]
     * @Return: com.crmeb.core.common.CommonResult<java.lang.String>
     * @Author: wangzh
     * @Date: 2022/11/7 16:44
     */
    public void deliverGoods(String orderSn, String dlyCodes, String shipNos) throws Exception {
        DeliverGoods deliverGoods = new DeliverGoods();
        Login();
        ShippingApiInputDto inputDto = new ShippingApiInputDto();
        inputDto.setAccountId(accountId);
        inputDto.setMemberId(memberId);
        inputDto.setAppkey(appKey);
        inputDto.setUrl(domain);
        inputDto.setTimestamp(System.currentTimeMillis());
        inputDto.setSecret(secret);
        inputDto.setDlyCodes(dlyCodes);
        inputDto.setOrderSn(orderSn);
        inputDto.setShipNos(shipNos);
        String result = deliverGoods.deliverGoods(inputDto);
        log.info("--------------- 推送订单发货通知, 商户号: {}, 订单号: {}, 物流代码: {}, 返回信息: {} ---------------", "27", orderSn, dlyCodes, result);
        if (!JSONObject.parseObject(result).getBoolean("success")){
            log.error("--------------------- 海带云发货失败 -------------------");
        }
    }

    /**
     * 功能描述: 海带云登陆
     * @Param: []
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/11/7 16:45
     */
    private void Login() throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("appkey", appKey);
        map.put("secret", secret);
        map.put("username", username);
        map.put("password", MD5Util.MD5(password).toLowerCase());
        String params = HaidaiApiUtils.getApiParams(map, secret);
        String response = HaidaiApiUtils.doGet(login + "?" + params);
        JSONObject responseJson = JSONObject.parseObject(response);
        Integer result = responseJson.getInteger("result");
        if (result == 0) {
            log.error(responseJson.getString("message"));
            return;
        }
        JSONObject data = responseJson.getJSONObject("data");
        //member_id,accountId,token
        accountId = data.getString("accountId");
        memberId = data.getString("memberId");
        token = data.getString("token");
    }

    //海带云退单
    //退单原因列表（中文原因，字符要求完全一致）：1 身份证重复2 地址异常：地址中不能出现关于超市、母婴店、药店等类似的字眼3 地址超过购买限额4 联系方式有误5 报关失败6 收件人信息重复7 单证审核不通过8 身份证海关封号10 身份证号码错误20 身份证号码与姓名不对应30 身份验证失败40 地址不详50 地址重复60 联系方式超过购买限额70 身份信息超过购买限额80 订单商品缺货90 物流配送无法联系到收货人95 其它96 未上传身份证照片
    private String batchAddExceptionReply(String orderSn, Integer returnReason) throws Exception {
        DeliverGoods deliverGoods = new DeliverGoods();
        Login();
        BatchAddExceptionReplyApiInputDto inputDto = new BatchAddExceptionReplyApiInputDto();
        inputDto.setAccountId(accountId);
        inputDto.setMemberId(memberId);
        inputDto.setAppkey(appKey);
        inputDto.setUrl(domain);
        inputDto.setTimestamp(System.currentTimeMillis());
        inputDto.setSecret(secret);
        inputDto.setOrderSns(orderSn);
        inputDto.setReturnReason(returnReason);
        return deliverGoods.batchAddExceptionReply(inputDto);
    }

    /**
     * 功能描述: 海带云退单
     * 待加入业务
     * @Param: [args]
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/11/10 15:27
     */
    @Override
    public void SeatentRefund() {
        try {
            // TODO 目前订单号、退款原因固定
            String result = batchAddExceptionReply("202211091981894147", ReturnReasonEnum.OTHER.getCode());
            //请求退单响应
            JSONObject response = JSONObject.parseObject(result);
            System.out.println(response);
            if (Objects.nonNull(response.getJSONObject("data"))){
                JSONObject data = response.getJSONObject("data");
                if (StringUtils.isNotBlank(data.getString("orderSn"))){
                    log.info("------------------- 海带云退单成功，订单号：{}，申请单号：{}，订单id：{}，售后单id：{} ------------------", data.getString("orderSn"), data.getString("applyNo"), data.getString("orderId"), data.getString("returnOrderId"));
                    // TODO 退单成功逻辑
                }
                if (StringUtils.isNotBlank(data.getString("alreadyReturnOrderIds"))){
                    // TODO 海带云退单失败处理流程
                    log.info("------------------- 海带云退单失败，原因：已经退单，订单号：{} -----------------", data.getString("alreadyReturnOrderIds"));
                } else if (StringUtils.isNotBlank(data.getString("errorOrderIds"))){
                    log.info("------------------- 海带云退单失败，原因：错误订单号，订单号：{} -----------------", data.getString("alreadyReturnOrderIds"));
                } else if (StringUtils.isNotBlank(data.getString("noGoods"))){
                    log.info("------------------- 海带云退单失败，原因：没有商品订单号，订单号：{} -----------------", data.getString("alreadyReturnOrderIds"));
                } else if (StringUtils.isNotBlank(data.getString("notAllowOrderIds"))){
                    log.info("------------------- 海带云退单失败，原因：不允许的订单号，订单号：{} -----------------", data.getString("alreadyReturnOrderIds"));
                } else if (StringUtils.isNotBlank(data.getString("unOrderIds"))){
                    log.info("------------------- 海带云退单失败，原因：非订单号的订单号，订单号“{} -----------------", data.getString("alreadyReturnOrderIds"));
                }
            } else {
                log.error("------------------ 海带云退单失败：{} ------------------", response.getString("message"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("-------------------- 海带云退单失败：{} --------------------", e.getMessage());
        }
    }

    @Override
    public CommonResult<String> annualLimit(List<String> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)){
            return CommonResult.failed("参数为空");
        }
//        list(Wrappers.<Relation>lambdaQuery().eq(Relation::getSubCode, PlatP
        List<StoreOrder> storeOrders = storeOrderService.list(Wrappers.<StoreOrder>lambdaQuery().in(StoreOrder::getOrderId, orderIds));
        if (CollectionUtils.isEmpty(storeOrders)){
            return CommonResult.failed("订单不存在");
        }
        Map<String, Integer> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        for (StoreOrder storeOrder : storeOrders) {
            String realName = StringUtils.defaultString(storeOrder.getPayName(),storeOrder.getRealName());
            String idCard = storeOrder.getIdCard();
            if (StringUtils.isAnyBlank(realName,idCard)){
                continue;
            }
            CommonResult<String> result = pushWarehouseFactory.getServiceInstance(1,"9610").personalQuota(storeOrder);
            String dataStr = result.getData();
            JSONObject resultObj = JSON.parseObject(dataStr);
            if (!Objects.equals(resultObj.getString("errorMsg"),"success")){
                continue;
            }
            JSONObject data = resultObj.getJSONObject("data");
            Integer remaining = data.getInteger("remaining");
            map.put(storeOrder.getOrderId(),remaining);
            String userPhone = storeOrder.getUserPhone();
            if (userPhone.contains("0|")){
                userPhone = userPhone.replace("0|","");
            }
            List<User> userList =  userService.list(Wrappers.<User>lambdaQuery().eq(User::getPhone, userPhone));
            if (CollectionUtils.isNotEmpty(userList)){
                list.add(storeOrder.getOrderId()+","+"Y"+","+remaining);
            }else {
                list.add(storeOrder.getOrderId()+","+"N"+","+remaining);
            }


        }
        System.out.println(JSON.toJSONString(list));
        return null;
    }

    public static void main(String[] args) {
        String userPhone = "0|+86 13706655728";
        if (userPhone.contains("0|")){
            userPhone = userPhone.replace("0|","");
        }
        System.out.println(userPhone);
    }
}

